单击带有RegisterStartupScript的多个按钮
本文关键字:按钮 RegisterStartupScript 单击 | 更新日期: 2023-09-27 18:21:29
我有一个ASP内容页面,在一个UpdatePanel中有三个网格,每个网格都有一个单独的刷新按钮。加载页面时,网格为空。如果我单击每个刷新按钮,一次一个,并在每个步骤之间等待,那么所有三个网格都将正确填充。
在这个页面的第一个版本中,我会在呈现初始页面加载之前预先填充网格。然而,每个网格刷新都很慢,我想改善用户体验——最初的加载大约需要30秒。我想我可以AJAX化页面,这样它首先可以快速加载(使用空网格),然后所有三次刷新都独立于Javascript启动,并且每个网格在其各自的刷新调用返回后立即填充,无论它们的准备顺序如何。这样,用户就不必等到所有三个都完成后,才能获得至少一些数据。
如果我只想自动化一个网格的初始填充,我可以很容易地使用这种技术:
if (!IsPostBack)
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "document.getElementById('" + btnRefreshGridA.ClientID + "').click();", true);
当只有一个长时间运行的报告我想发布时,我已经使用过很多次了,在这里它很好用。但这是一个我以前从未考虑过的场景——如果我尝试为多个网格这样做:
if (!IsPostBack)
{
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "document.getElementById('" + btnRefreshGridA.ClientID + "').click();", true);
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridB", "document.getElementById('" + btnRefreshGridB.ClientID + "').click();", true);
}
那么唯一完成的刷新是最后一次。我想我不应该感到惊讶,因为如果我手动复制它,并立即单击一个又一个刷新按钮,我会得到相同的结果——第一个AJAX调用似乎被放弃了。这就是发生的事情吗?
有可能完成我想要做的事情吗?协调多个独立的、同时进行的AJAX调用的正确方法是什么?我怀疑我根本不应该使用这些按钮,但当只涉及一个按钮时,我已经在这种方法上取得了很大成功。我尝试过将点击组合到一个脚本中,并尝试过将每个网格/按钮对包装在自己的UpdatePanel中,但这两种变体都得到了相同的结果。
从这里,我发现了一个javascript事件队列,它可以帮助我做我想做的事情:
<script type="text/javascript">
Sys.Application.add_load(ApplicationLoadHandler)
function ApplicationLoadHandler(sender, args) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (!prm.get_isInAsyncPostBack()) {
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(CompleteRequest);
}
}
var myQueue = new Array();
function InitializeRequest(sender, args) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {// if it's working on another request, cache the current item that cause the request
args.set_cancel(true);
Array.add(myQueue, args.get_postBackElement());
}
}
function CompleteRequest(sender, args) {
if (myQueue.length > 0) {// fire corresponding event again of the item cached
$get(myQueue[0].id).click();
Array.removeAt(myQueue, 0);
}
}
if (typeof (Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
</script>
这也可以从代码隐藏中呈现,如下所示:
StringBuilder script = new StringBuilder();
script.Append("Sys.Application.add_load(ApplicationLoadHandler)'n");
script.Append("function ApplicationLoadHandler(sender, args) {'n");
script.Append(" var prm = Sys.WebForms.PageRequestManager.getInstance();'n");
script.Append(" if (!prm.get_isInAsyncPostBack()) {'n");
script.Append(" prm.add_initializeRequest(InitializeRequest);'n");
script.Append(" prm.add_endRequest(CompleteRequest);'n");
script.Append(" }'n");
script.Append("}'n");
script.Append("var myQueue = new Array();'n");
script.Append("function InitializeRequest(sender, args) {'n");
script.Append(" var prm = Sys.WebForms.PageRequestManager.getInstance();'n");
script.Append(" if (prm.get_isInAsyncPostBack()) {'n");
script.Append(" args.set_cancel(true);'n");
script.Append(" Array.add(myQueue, args.get_postBackElement());'n");
script.Append(" }'n");
script.Append("}'n");
script.Append("function CompleteRequest(sender, args) {'n");
script.Append(" if (myQueue.length > 0) {'n");
script.Append(" $get(myQueue[0].id).click();'n");
script.Append(" Array.removeAt(myQueue, 0);'n");
script.Append(" }'n");
script.Append("}'n");
script.Append("if (typeof (Sys) !== '"undefined'") Sys.Application.notifyScriptLoaded();");
ClientScript.RegisterStartupScript(this.GetType(), "EventQueue", script.ToString(), true);
不管添加这个队列脚本的方法是什么,我发现我需要在点击按钮时添加一个轻微的延迟来让他们排队:
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "setTimeout('"document.getElementById('" + btnRefreshGridA.ClientID + "').click();'",100);", true);
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridB", "setTimeout('"document.getElementById('" + btnRefreshGridB.ClientID + "').click();'",100);", true);
如果没有setTimeout,只有最后一个按钮才能像以前一样完成刷新。
从根本上讲,刷新调用实际上并不是多线程的;它们是串行执行的。然而,我现在对用户体验感到满意。