jQuery $(document).ready和UpdatePanels?

2020/09/26 00:41 · javascript ·  · 0评论

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

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

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

不仅在首页加载时,而且在每次UpdatePanel触发部分页面更新时,建议在jQuery中进行接线的推荐方法是什么?我应该使用ASP.NET ajax生命周期来代替$(document).ready吗?

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().on(),因此在这种情况下,最好重新订阅。

<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>

在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>

所以...只是以为有人可能想知道这行得通。

升级到jQuery 1.3并使用:

$(function() {

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

});

注意:现场直播适用于大多数事件,但并非全部。文档中有完整列表

您也可以尝试:

<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事件,每次在客户端加载页面时都会执行该事件。

我的答案?

function pageLoad() {

  $(document).ready(function(){

等等

像魅力一样运作,许多其他解决方案惨遭失败。

我将使用以下方法之一:

  1. 将事件绑定封装在函数中,并在每次更新页面时运行它。您始终可以将事件绑定包含到特定元素,以免多次将事件绑定到相同元素。

  2. 使用livequery插件,该插件基本上可以自动为您执行方法一。您的首选项可能会有所不同,具体取决于您希望对事件绑定进行控制的程度。

这对我有用:

$(document).ready(function() {

    // Do something exciting

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

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

});

在这种情况下使用pageLoad()函数非常危险。您可能使事件多次关联。我也会远离.live(),因为它附加到document元素上并且必须遍历整个页面(缓慢而low脚)。

到目前为止,我所看到的最好的解决方案是在更新面板外部的包装器上使用jQuery .delegate()函数并利用冒泡。除此之外,您始终可以使用设计用于UpdatePanels的Microsoft Ajax库连接处理程序。

$(document).ready(function (){...})页面回发后不起作用时,请按如下方式在Asp.page中使用JavaScript函数pageLoad:

<script type="text/javascript" language="javascript">
function pageLoad() {
// Initialization code here, meant to run once. 
}
</script>

我遇到了类似的问题,发现最有效的方法是依靠事件冒泡和事件委托来处理它。关于事件委托的一件好事是,一旦设置,您就不必在AJAX更新后重新绑定事件。

我在代码中所做的是在更新面板的父元素上设置一个委托。更新时不会替换此父元素,因此事件绑定不受影响。

有很多不错的文章和插件可以处理jQuery中的事件委托,并且该功能很可能会纳入1.3版本中。我参考的文章/插件是:

http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

一旦您了解了发生的事情,我想您会发现这是一个更加优雅的解决方案,比记住每次更新后重新绑定事件更可靠。这还具有一个额外的好处,即在页面卸载时为您提供一个取消绑定的事件。

FWIW,我在使用mootools时遇到了类似的问题。重新添加事件是正确的举动,但需要在请求结束时完成。

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function() {... 

如果beginRequest使您获得空引用JS异常,则要记住一点。

干杯

这是一个很棒的插件,可用于更新面板:

http://updatepanelplugin.codeplex.com/

pageLoad = function () {
    $('#div').unbind();
    //jquery here
}

pageLoad函数非常适合这种情况,因为它在初始页面加载和每次updatepanel异步回发时运行。我只需要添加unbind方法就可以使jquery在updatepanel回发上工作。

http://encosia.com/document-ready-and-pageload-are-not-the-same/

我的回答是基于上面的所有专家评论,但下面的代码是任何人都可以用来确保在每次回发和每次异步回发中仍将执行JavaScript代码的以下代码。

就我而言,我在页面内有一个用户控件。只需将以下代码粘贴到用户控件中即可。

<script type="text/javascript"> 
        var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_endRequest(EndRequestHandler);
    function EndRequestHandler(sender, args) {
        if (args.get_error() == undefined) {
            UPDATEPANELFUNCTION();
        }                   
    }

    function UPDATEPANELFUNCTION() {
        jQuery(document).ready(function ($) {
            /* Insert all your jQuery events and function calls */
        });
    }

    UPDATEPANELFUNCTION(); 

</script>

每次加载后,“更新面板”始终用其内置的Scriptmanager脚本替换您的Jquery。如果像这样使用pageRequestManager的实例方法,那就更好了……

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest)
    function onEndRequest(sender, args) {
       // your jquery code here
      });

它将工作正常...

使用以下脚本,并相应地更改脚本的主体。

       <script>
        //Re-Create for on page postbacks
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_endRequest(function () {
           //your codes here!
        });
    </script>

回应Brian MacKay的回答:

我通过ScriptManager将JavaScript注入到页面中,而不是直接将其放入UserControl的HTML中。就我而言,我需要滚动到UpdatePanel完成并返回后显示的表单。这在文件后面的代码中。在我的示例中,我已经在主内容页面上创建了prm变量。

private void ShowForm(bool pShowForm) {
    //other code here...
    if (pShowForm) {
        FocusOnControl(GetFocusOnFormScript(yourControl.ClientID), yourControl.ClientID);
    }
}

private void FocusOnControl(string pScript, string pControlId) {
    ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "focusControl_" + pControlId, pScript, true);
}

/// <summary>
/// Scrolls to the form that is made visible
/// </summary>
/// <param name="pControlId">The ClientID of the control to focus on after the form is made visible</param>
/// <returns></returns>
private string GetFocusOnFormScript(string pControlId) {
    string script = @"
    function FocusOnForm() {
        var scrollToForm = $('#" + pControlId + @"').offset().top;
        $('html, body').animate({ 
            scrollTop: scrollToForm}, 
            'slow'
        );
        /* This removes the event from the PageRequestManager immediately after the desired functionality is completed so that multiple events are not added */
        prm.remove_endRequest(ScrollFocusToFormCaller);
    }
    prm.add_endRequest(ScrollFocusToFormCaller);
    function ScrollFocusToFormCaller(sender, args) {
        if (args.get_error() == undefined) {
            FocusOnForm();
        }
    }";
    return script;
}
Sys.Application.add_load(LoadHandler); //This load handler solved update panel did not bind control after partial postback
function LoadHandler() {
        $(document).ready(function () {
        //rebind any events here for controls under update panel
        });
}
本文地址:http://javascript.askforanswer.com/jquery-document-readyheupdatepanels.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!