应用UpdatePanel后jQuery事件失效问题的解决方法

时间:2021-06-17 02:18:17

问题描述
当第一次加载页面时,$(document).ready(function(){ })中的jQuery语句会正常执行,但是当页面部分刷新后,就不会执行了。

问题示例代码
1、$(document).ready(function(){ })中动态绑定change、blur
$(document).ready(function(){ })中为UpdatePanel中的某个控件动态绑定change、blur事件,第一次加载页面时,事件会正常执行,当页面部分刷新后,事件就不执行了。

<head runat="server">
<title></title>
<script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#txtUserName").change(function () {
alert("用户名变了");
});
$("#txtPassword").blur(function () {
alert("密码失去了焦点");
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="main">
用户名:<input type="text" id="txtUserName" runat="server"/>
<br/>
密码:<input type="text" id="txtPassword" runat="server"/>
<br/>
其他:<input type="text" id="txtOther" runat="server"/>
<br/>
<asp:Button ID="btnSearch" runat="server" Text="点击" onclick="btnSearch_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

2、$(document).ready(function(){ })中执行其他jQuery语句
$(document).ready(function(){ })中对UpdatePanel中的某个控件进行一些操作,第一次加载页面时,事件会正常执行,当页面部分刷新后,事件就不执行了。

<head runat="server">
<title></title>
<script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var wh = document.documentElement.clientWidth * 1.3;
$("#datas").width(wh);
var h = document.documentElement.clientHeight - 200;
//默认固定表头,设置固定几列
FixTable("datas", 1, wh, h, "scroll", "auto");
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<!--main start-->
<div class="main">
<div class="r">
<div>
<table id="datas" class="tab-datagrid1" cellspacing="0" cellpadding="0" width="100%">
<thead>
……
</thead>
<tbody style="overflow-x: scroll;">
……
</tbody>
</table>
<table width="100%" cellpadding="0" cellspacing="0">
……
</table>
</div>
</div>
<div class="clear">
</div>
</div>
<!--main end-->
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

3、意外收获:onchange、onblur
通过onchange、onblur对UpdatePanel中的某个控件进行事件绑定时,第一次加载页面时,事件会正常执行,当页面部分刷新后,事件照样正常执行。

<head runat="server">
<title></title>
<script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
function IptChange() {
alert("用户名变了");
}

function IptBlur() {
alert("密码失去了焦点");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="main">
用户名:<input type="text" id="txtUserName" runat="server" onchange="IptChange()"/>
<br/>
密码:<input type="text" id="txtPassword" runat="server" onblur="IptBlur()"/>
<br/>
其他:<input type="text" id="txtOther" runat="server"/>
<br/>
<asp:Button ID="btnSearch" runat="server" Text="点击" onclick="btnSearch_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

分析1:UpdatePanel
UpdatePanel主要用于局部刷新,避免整个页面的PostBack。
UpdatePanel实现局部刷新的核心在于MicrosoftAjaxWebForm.js文件,它的局部刷新过程就是将页面提交到服务器(包括ViewState),执行服务端代码后异步将UpdatePanel内的HTML重新呈现。在此过程中,页面的其他部分并没有状态更改。

分析2:jQuery
jQuery可以通过简单的代码对HTML元素添加各种属性和事件句柄,我们可以在这里看到官方的文档
Tutorials:How jQuery Works:http://docs.jquery.com/How_jQuery_Works
在这里我们得知,jQuery有个重要的事件标记“ready”,一般对HTML元素的效果和事件句柄都要通过ready事件来添加。官方对此的说明是:ready事件会在DOM完全加载后运行一次,至此问题的原因差不多明白了。示例代码如下:

$(document).ready(function () {
$(“p”).text("The DOM is now loaded and can be manipulated.");
});

jQuery失效的原因
因为在UpdatePanel局部刷新之后,其中的元素A被重写,而此时整个DOM树并没有重新加载,所以jQuery的ready事件没有触发,因此A就失去了原有的特效。

解决方案
我们可以将ready事件中执行的代码提取出来,然后通过捕获ScriptManager的EndRequest事件,在每次UpdatePanel局部刷新后执行一次jQuery初始化代码,当然原来$(document).ready(function(){ });中的代码仍然需要使用,代码如下:

<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
Method1();
Method2();
});

$(document).ready(function () {
Method1();
Method2();
});

function Method1(){
$('#userName').blur(function () {
//具体代码
});
}
......

</script>