如何在更新面板回发后执行 javascript 回调?

当用户将页面的某些元素悬停时,我使用了一个 jQuery 技巧插件来显示帮助技巧。

我需要注册的插件事件后,页面加载使用 css 选择器。

问题是我使用的是 ASP.NET 更新面板,在第一次回发之后,提示停止工作,因为更新面板替换了页面内容,但是没有重新绑定 javascript 事件。

我需要一种在更新面板刷新其内容后执行 javascript 回调的方法,这样我就可以重新绑定 javascript 事件,让提示再次工作。

有什么办法吗?

69009 次浏览

这可能远远不是最优雅的解决方案,但它仍然是一个解决方案:

public class UpdatePanel : System.Web.UI.UpdatePanel
{
/// <summary>
/// Javascript to be run when the updatepanel has completed updating
/// </summary>
[Description("Javascript to be run when the updatepanel has completed updating"),
Category("Values"),
DefaultValue(null),
Browsable(true)]
public string OnUpdateCompleteClientScript
{
get
{
return (string)ViewState["OnUpdateCompleteClientScript"];
}
set
{
ViewState["OnUpdateCompleteClientScript"] = value;
}
}


protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
if(!string.IsNullOrEmpty(this.OnUpdateCompleteClientScript))
Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID, string.Concat("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args){for(var panelId in sender._updatePanelClientIDs){if(sender._updatePanelClientIDs[panelId] == '", this.ClientID, "'){", this.OnUpdateCompleteClientScript, "}}});"), true);
}
}

像这样使用它:

<uc:UpdatePanel OnUpdateCompleteClientScript="alert('update complete');">
<!-- stuff in here -->
</uc:UpdatePanel>

当然,您需要在您的 webconfig 或页面中注册自定义控件,以便像这样使用它。

编辑: 还有,你看过 Jquery.live?了吗

不要将 jQuery 代码放在 $(document).ready()中,而是将它放在 $(document).ready()

function pageLoad(sender, args) {
...
}

pageLoad在每次回发、同步或异步之后执行。pageLoad是 ASP.NET AJAX 中用于此目的的保留函数名。另一方面,当 DOM 最初准备好/加载时,$(document).ready()只执行一次。

看这个 ASP.NET AJAX 客户端生命周期事件概述

PageLoad 不起作用,我使用了以下代码:

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


function pageLoaded() {
}

如果希望在加载 UpdatePanel 之前和之后执行特定操作,可以像下面这样覆盖 BeginPostbackRequestEndPostbackRequest:

var postbackControl = null;
var updatePanels = null;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginPostbackRequest);
prm.add_endRequest(EndPostbackRequest);


function BeginPostbackRequest(sender, args) {
prm._scrollPosition = null;
postbackControl = args.get_postBackElement();
postbackControl.disabled = true;
updatePanels = args._updatePanelsToUpdate;
// do your stuff
}


function EndPostbackRequest(sender, args) {
// do your stuff
postbackControl.disabled = false;
postbackControl = null;
updatePanels = null;
}

如果您只想处理更新面板提供的 HTML,那么这非常方便。有些操作需要更多的资源,在 pageLoad上处理整个 DOM 树有些过分。

使用 pageLoadedevent 并检查是回调还是回发:

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(function (sender, args) {
if (args._panelsUpdated && args._panelsUpdated.length > 0) {
//callback;
}
else {
//postback;
}
});