在Ajax更新之后重新绑定jQuery中的事件(updatepanel)


80

我的页面上有几个input和option元素,每个元素(几乎)都有一个事件,一旦它们发生更改,便会更新页面上的某些文本。我使用的jQuery真的很酷:)

我还使用Microsoft Ajax框架,并使用UpdatePanel。我这样做的原因是,某些元素是基于某些服务器端逻辑在页面上创建的。我真的不想解释为什么我使用UpdatePanel-即使可以(相当费力)将其重写为仅使用jQuery,我仍然希望该UpdatePanel。

您可能猜对了-一旦我在UpdatePanel上进行了回发,jQuery事件就会停止工作。我实际上期望如此,因为“回发”并不是真正的新回发,因此绑定事件的document.ready中的代码不会再次被触发。我还通过在jQuery帮助库中阅读它来证实自己的怀疑。

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


这非常类似于这样的问题:stackoverflow.com/questions/256195/...
丹·赫伯特

Answers:


85

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

function pageLoad(sender, args)
{
   if (args.get_isPartialLoad())
   {
       //Specific code for partial postbacks can go in here.
   }
}

1
没问题-但这只是其中一种方法。如果需要更大的灵活性,请检查PageRequestManager类上的endRequest事件。
Phil Jenkins

太棒了!我用您的pageLoad替换了我的jquery $ {document).ready(没有if块),它解决了我的问题!
克里斯,2009年

10
注意:页面上仅执行一个“ pageLoad”函数-最后一个定义。因此,如果需要执行的动作位于不同的控件上-有更简单的方法来实现所需的行为-例如“ Sys.Application.add_load”。
Paulius

23

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


这对我来说是最好的解决方案,因为我的jQuery标记大部分都封装在页面上的几个用户控件内。
凯尔·B

1
你可以用datepicker发布示例吗?
Perica Zivkovic

我只是使用“ on”来绑定到执行异步发布触发的面板内的下拉列表。直到我还添加了@Phil Jenkins的回答,它才起作用。我不确定是异步发布还是完整发布,但是否会有所不同。邮寄回来后,活页夹未处理。
Casey 2015年

22
Sys.Application.add_load(initSomething);
function initSomething()
{
  // will execute on load plus on every UpdatePanel postback
}

14

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

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

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

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

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

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


太棒了!(该文档)使用以下方法很不错.... $(document).on('click','#tagsAdd',function()不管我有多少个更新面板,我都在拆分页面的内容:) Thx
Martin Sansone-MiOEE 2014年

9

使用以下代码

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

8

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

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

这里的简单例子。

jQuery插件,方便进行事件委托。

PS:我有99%的把握会在下一个版本中将委托加入jQuery核心。


5

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

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

4

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

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


       }

            </script>

        </ContentTemplate>
    </asp:UpdatePanel>

在“ if”中,您可以将每次updatepanel执行AsyncPostBack时都需要执行的代码放入。


2

使用jQuery的新“实时”方法绑定事件。它将事件绑定到您当前的所有元素以及将来的所有元素。查清!:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.