Ajax 更新后在 jQuery 中重新绑定事件(更新面板)

Posted

技术标签:

【中文标题】Ajax 更新后在 jQuery 中重新绑定事件(更新面板)【英文标题】:Rebinding events in jQuery after Ajax update (updatepanel) 【发布时间】:2010-09-23 00:32:00 【问题描述】:

我的页面上有几个输入和选项元素,每个(几乎)都附加了一个事件,以便在页面上的某些文本发生更改时更新它们。我使用的 jQuery 真的很酷 :)

我还使用 Microsoft 的 Ajax 框架,利用 UpdatePanel。我这样做的原因是某些元素是基于某些服务器端逻辑在页面上创建的。我真的不想解释为什么我使用 UpdatePanel - 即使它可以(它可以通过相当大的努力)被重写为仅使用 jQuery 我仍然想要那个 UpdatePanel。

您可能已经猜到了——一旦我在 UpdatePanel 上进行了回发,jQuery 事件就会停止工作。我实际上已经预料到了这一点,因为“回发”并不是真正的新回发,所以我在 document.ready 中绑定事件的代码不会再次被触发。我还通过阅读 jQuery 帮助库中的相关内容证实了我的怀疑。

无论如何,在 UpdatePanel 完成更新 DOM 后,我仍然面临重新绑定控件的问题。我最好需要一个不需要向页面添加更多 .js 文件(jQuery 插件)的解决方案,但只要能够捕获 UpdatePanel 的“更新后”,我就可以调用我的方法来重新绑定所有表单元素。 .

【问题讨论】:

这与这个问题非常相似:***.com/questions/256195/… 【参考方案1】:

由于您使用的是 ASP.NET AJAX,因此您可以访问 pageLoad 事件处理程序,该处理程序会在每次页面回发时被调用,无论是全部还是部分来自 UpdatePanel。您只需将功能放入您的页面,无需连接。

function pageLoad(sender, args)

   if (args.get_isPartialLoad())
   
       //Specific code for partial postbacks can go in here.
   

【讨论】:

没问题 - 顺便说一句,这只是一种方法。如果您需要更大的灵活性,请查看 PageRequestManager 类的 endRequest 事件。 太棒了!我用你的 pageLoad(没有 if 块)替换了我的 jquery $(document).ready,它解决了我的问题! 警告:只有一个“pageLoad”函数在页面上执行——最后一个定义的。因此,如果需要执行的操作驻留在不同的控件上 - 有更简单的方法来实现所需的行为 - 例如“Sys.Application.add_load”。【参考方案2】:

或者您可以通过on() 方法查看最新的jQuery 实时功能。

【讨论】:

这对我来说是最好的解决方案,因为我的大部分 jQuery 标记都封装在页面上的多个用户控件中。 你能用 datepicker 发布例子吗? 我只是使用“on”来绑定到执行异步后触发的面板内的下拉列表。它没有工作,直到我还包括@Phil Jenkins 上面的答案。我不确定它是异步帖子还是完整回帖是否会有所不同,但是可以。回发后活页夹没有处理它。【参考方案3】:
Sys.Application.add_load(initSomething);
function initSomething()

  // will execute on load plus on every UpdatePanel postback

【讨论】:

【参考方案4】:

从 jQuery 1.7 开始,推荐的方法是使用jQuery's .on() 语法。

但是,请确保您在 document 对象上设置事件,而不是在 DOM 对象本身上。例如,这将在 UpdatePanel 回发后中断

$(':input').on('change', function() ...);

... 因为 ':inputs' 已被重写。改为这样做:

$(document).on('change', ':input', function() ...);

只要文档还在,任何输入(包括来自 UpdatePanel 刷新的输入)都会触发更改处理程序。

【讨论】:

太棒了! (文档)使用以下内容很好地工作...... $(document).on('click','#tagsAdd',function () 无论我有多少更新面板分解了页面的内容:) Thx 【参考方案5】:

使用以下代码

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);

function pageLoaded(sender, args) 
    var updatedPanels = args.get_panelsUpdated();
    // check if Main Panel was updated 
    for (idx = 0; idx < updatedPanels.length; idx++) 
        if (updatedPanels[idx].id == "<%=upMain.ID %>") 
            rebindEventsForMainPanel();
            break;
        
    

【讨论】:

【参考方案6】:

您可以使用 jQuery 和事件委托。基本上将事件挂钩到容器而不是每个元素并查询 event.target 并基于此运行脚本。

它有多种好处,可以减少代码噪音(无需重新绑定)。它是 浏览器内存也更容易(DOM中绑定的事件更少。)

快速示例here。

jQuery plugin 便于事件委托。

P.S 我有 99% 的把握在下一个版本中委托将在 jQuery 核心中。

【讨论】:

【参考方案7】:

使用以下代码,您需要验证控件是否会使用数据选择器:

    <script type="text/javascript" language="javascript">

         Sys.WebForms.PageRequestManager.getInstance().add_endRequest(addDataPicker); 
         function addDataPicker(sender, args)
         
            var fchFacturacion = document.getElementById('<%= txtFechaFacturacion.ClientID %>');
            if (fchFacturacion != null) 
               $(fchFacturacion).datepicker( onSelect: function ()  , changeMonth: true, changeYear: true, showOn: 'button', buttonImage: '../Imagenes/calendar.gif', buttonImageOnly: true);
          

    </script>

     <asp:UpdatePanel ID="upEjem" runat="server" UpdateMode="Conditional">
       <ContentTemplate>
              <div id="div1" runat="server" visible="false">
                  <input type="text" id="txtFechaFacturacion" 
                      name="txtFechaFacturacion" visible="true"
                      readonly="readonly" runat="server" />
              </div>
       </ContentTemplate>
     </asp:UpdatePanel>

【讨论】:

【参考方案8】:

         <script type="text/javascript">
             function pageLoad() 

                 if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) 


       

            </script>

        </ContentTemplate>
    </asp:UpdatePanel>

您可以将每次更新面板执行 AsyncPostBack 时需要执行的代码放入“if”中。

【讨论】:

【参考方案9】:

使用 jQuery 的新 'live' 方法绑定您的事件。它会将事件绑定到您当前的所有元素以及所有未来的元素。查清! :)

【讨论】:

以上是关于Ajax 更新后在 jQuery 中重新绑定事件(更新面板)的主要内容,如果未能解决你的问题,请参考以下文章

JSF/PrimeFaces ajax 更新破坏了 jQuery 事件侦听器函数绑定

ASP.NET MVC 主视图引用的js(jquery)在分部视图中无效,如何解决?

jquery绑定的事件对ajax刷新出的数据不生效,on可能受jquery版本影响

jquery中ajax的相关事件汇总

如何确定事件是不是已与 jQuery 绑定 [重复]

AJAX 成功后在 tooltipster 中更新 html 内容