jQuery $(document).ready 和 UpdatePanels?

IT技术 javascript jquery asp.net asp.net-ajax jquery-events
2021-01-16 14:07:53

我正在使用 jQuery 在 UpdatePanel 内的元素上连接一些鼠标悬停效果。事件绑定在$(document).ready. 例如:

$(function() {    
    $('div._Foo').bind("mouseover", function(e) {
        // Do something exciting
    });    
});

当然,这在第一次加载页面时工作正常,但是当 UpdatePanel 执行部分页面更新时,它不会运行并且鼠标悬停效果在 UpdatePanel 内不再起作用。

不仅在第一页加载时,而且每次 UpdatePanel 触发部分页面更新时,在 jQuery 中连接东西的推荐方法是什么?我应该使用 ASP.NET ajax 生命周期而不是$(document).ready?

6个回答

UpdatePanel 在更新时完全替换更新面板的内容。这意味着您订阅的那些事件不再订阅,因为该更新面板中有新元素。

我为解决此问题所做的工作是在每次更新后重新订阅我需要的事件。$(document).ready()用于初始加载,然后使用 Microsoft 的PageRequestManager(如果您的页面上有更新面板,则可用)重新订阅每个更新。

$(document).ready(function() {
    // bind your jQuery events here initially
});

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_endRequest(function() {
    // re-bind your jQuery events here
});

PageRequestManager是一个 javascript 对象,如果页面上有更新面板,它会自动可用。只要 UpdatePanel 在页面上,除了上面的代码之外,您不需要执行任何其他操作即可使用它。

如果您需要更详细的控制,此事件传递的参数类似于 .NET 事件传递参数的方式,(sender, eventArgs)因此您可以查看引发事件的原因,并且仅在需要时重新绑定。

以下是 Microsoft 文档的最新版本:msdn.microsoft.com/.../bb383810.aspx


根据您的需要,您可能拥有的更好选择是使用 jQuery 的.on(). 这些方法比在每次更新时重新订阅 DOM 元素更有效。但是,在使用此方法之前请阅读所有文档,因为它可能满足也可能不满足您的需求。有很多 jQuery 插件无法重构以使用.delegate()or .on(),因此在这些情况下,您最好重新订阅。

解释时请更准确。我的意思是使用示例比几行分散的代码要好得多。见布赖恩·麦凯解释。这是完美的!
2021-03-11 14:07:53
@GabyakaG.Petrioli 我意识到它已被取代,但由于这个答案似乎解决了一个常见问题,我想最大限度地提高与尚未升级的旧版本 jQuery 的兼容性。我之前推荐的答案.live(...)已在 1.7 中正式弃用,可能会在未来版本中删除。我特意选择了.delegate()它,因为它在 jQuery 中已经支持了一段时间,并且不太可能很快被删除。但是,.on()对于可以使用它的人,我也会升级我的答案以提及
2021-03-23 14:07:53
@Dan,从 jQuery 1.7 开始,.delegate()已被取代.on()
2021-04-04 14:07:53
@AhmedSamy 不建议再使用jQuery.delegate()它已被jQuery.on()首选 API取代delegate()只是特定用途的包装器,on()将来可能会被弃用。我之前提到的评论delegate()是一年多前写的,当时 jQuery 1.7(引入了on()API)刚刚发布。由于 jQuery 1.9 已经发布并且 2.0 正在准备发布测试版,因此避免delegate()在任何新代码中使用是一个好主意
2021-04-07 14:07:53
最好在 $(document).ready 中声明并连接 prm var,因为 Sys 可能尚未声明(取决于脚本所在的位置)。
2021-04-09 14:07:53
<script type="text/javascript">

        function BindEvents() {
            $(document).ready(function() {
                $(".tr-base").mouseover(function() {
                    $(this).toggleClass("trHover");
                }).mouseout(function() {
                    $(this).removeClass("trHover");
                });
         }
</script>

即将更新的区域。

<asp:UpdatePanel...
<ContentTemplate
     <script type="text/javascript">
                    Sys.Application.add_load(BindEvents);
     </script>
 *// Staff*
</ContentTemplate>
    </asp:UpdatePanel>
适用于 <EditItemTemplate> 内的 asp:GridView TextBox
2021-03-20 14:07:53
此解决方案的问题在于,虽然它有效,但它会杀死 UpdatePanel 的异步回发 - 再次使 UpdatePanel 无用。(叹)
2021-03-23 14:07:53

在 UpdatePanel 中使用 jQuery 进行用户控制

这不是问题的直接答案,但我确实通过阅读我在此处找到的答案将这个解决方案放在一起,我认为有人可能会觉得它很有用。

我试图在用户控件中使用 jQuery textarea 限制器。这很棘手,因为用户控件在 UpdatePanel 内部运行,并且它在回调时丢失了绑定。

如果这只是一个页面,这里的答案将直接适用。但是,用户控件不能直接访问 head 标记,也不能直接访问 UpdatePanel,正如某些答案所假设的那样。

我最终把这个脚本块放在了我的用户控件标记的顶部。对于初始绑定,它使用 $(document).ready,然后从那里使用 prm.add_endRequest:

<script type="text/javascript">
    function BindControlEvents() {
        //jQuery is wrapped in BindEvents function so it can be re-bound after each callback.
        //Your code would replace the following line:
            $('#<%= TextProtocolDrugInstructions.ClientID %>').limit('100', '#charsLeft_Instructions');            
    }

    //Initial bind
    $(document).ready(function () {
        BindControlEvents();
    });

    //Re-bind for callbacks
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 

    prm.add_endRequest(function() { 
        BindControlEvents();
    }); 

</script>

所以......只是想有人可能想知道这是有效的。

在我的情况下,我使用 ScriptManager.RegisterClientScriptBlock 添加脚本,它在定义 Sys 之前添加脚本,所以我最终使用了 RegisterStartupScript(请参阅此处的区别
2021-03-16 14:07:53
我不能让这个为我的生活工作。然后我将它从头部移动到页脚并且它起作用了。不是肯定的,但我认为它需要在我使用的 ScriptManager 之后出现。
2021-03-30 14:07:53
很酷的答案!它在我的 asp.net 网络应用程序中就像一个魅力。+ 给你
2021-04-08 14:07:53

升级到 jQuery 1.3 并使用:

$(function() {

    $('div._Foo').live("mouseover", function(e) {
        // Do something exciting
    });

});

注意:实时适用于大多数事件,但不是全部。文档中有完整列表

使用实时修复更新面板的问题。无需跳箍。
2021-03-16 14:07:53
刚刚live()在IE7(jQuery 1.5.1 / VS2010 项目)中使用该方法时发现严重失败当使用live()一个UpdatePanel里面V3.5 ASP.NET一个普通AutoPostback<asp:DropDownList />原因,而不是预期的1浏览器发出额外的回传缺乏内容(中止)2个部分回发导致Page.IsPostBackfalse(杀死在我的束缚态控制)。我发现罪魁祸首是 live() 方法。我意识到按照规范 UpdatePanel 会中止第一次回发,但前提是队列中还有另一个没有回发。
2021-03-18 14:07:53
需要在页面加载上发生的事情呢?例如斑马条纹表?$('TABLE TR:nth-child(odd)').addClass('alt-row');
2021-03-31 14:07:53
只是为了更新,因为 jQuery 1.7 现在建议使用 .on() 代替
2021-04-08 14:07:53

你也可以试试:

<asp:UpdatePanel runat="server" ID="myUpdatePanel">
    <ContentTemplate>

        <script type="text/javascript" language="javascript">
        function pageLoad() {
           $('div._Foo').bind("mouseover", function(e) {
               // Do something exciting
           });
        }
        </script>

    </ContentTemplate>
</asp:UpdatePanel>

,因为 pageLoad() 是一个 ASP.NET ajax 事件,每次在客户端加载页面时都会执行该事件。

pageLoad 在更新面板的每个异步回发上复制事件。
2021-03-12 14:07:53