我的页面有一些需要在页面加载时运行的javascript。所述javascript需要找到ServerControl的客户端组件,它与$ find()一起使用。
当然,如果我直接将代码发送到页面上,它会在页面被读取时执行,并且因为它所依赖的任何内容尚未初始化而失败。
如果我将我的代码放在pageLoad()函数中,它运行得很好,因为asp.net会自动为任何名为pageLoad()的函数连接onload处理程序。问题是我真的不喜欢pageLoad()解决方案 - 主要是因为它是一个单一的全局名称。如果我使用pageLoad()提交一些代码,我只知道其他一些程序员将要复制该方法,在某个地方不合适,我们最终会得到一个包含两个或更多不同pageLoad()函数的页面,并且结果将是一堆神秘的错误,需要永远追查。
所以,我把我的代码放在一个传递给jquery的$(document).ready()的匿名函数中。这失败了,因为它在ServerControl的客户端组件存在之前运行。
因此,我将我的代码放在Sys.Application.add_load()传递给的匿名函数中。这也失败了,因为系统未定义。
所以我最终决定将我的代码放在Sys.Application.add_load()中,然后将它放在$(document).ready()调用的函数中。这样可行,但它几乎与pageLoad()一样令人心痛。
<script type="text/javascript">
$(document).ready(function(){
Sys.Application.add_load(function(){
var component = $find(<clientid>);
if (component) { <do something> }
});
});
</script>
必须有更好的方法来解决这个问题。
有什么想法吗?
答案 0 :(得分:19)
如果您可以控制代码隐藏,则可以通过以下方式注册要在启动时运行的JavaScript:
this.Page.ClientScript.RegisterStartupScript(
this.GetType(),
"StartupScript",
"Sys.Application.add_load(function() { functioncall(); });",
true);
只要您的组件已通过Sys.Application.add_init()加载,您应该没问题......
答案 1 :(得分:5)
我想为那些试图构建外部库并尝试在.NET中尽可能遵循不引人注目的javascript思维方式的人提供替代方案。
pageLoad是一种自动连接AJAX事件的绝佳方法,这些事件应该在每个页面加载时触发(无论该加载来自此页面的后退按钮导航,页面的前进按钮导航,AJAX回调,标准页面加载,等等,因为您不必担心等待ScriptManager存在于DOM中,并且它以一种有意义的方式命名,在大多数情况下(pageLoad vs. body.onload有点令人困惑)对于非.NET编码器,但对于.NET人员来说,有意义的是pageLoad会在每次页面加载时触发,包括在回调之后,因为服务器端Page_Load的行为是相同的。话虽如此,您的关注点很好 - 您不希望在给定页面上有两个pageLoad实例,因为它会中断。这是一个直接的javascript解决方案,对于所有开发人员来说都是安全的,允许使用pageLoad,不会担心存在的DOM,确保没有代码冲突,并且对我们来说非常有效。
在主javascript库中,定义pageLoad以及辅助函数:
if (!pageLoad) { var pageLoad = function (sender, args) {}; };
if (!mylibrarynamespace) {var mylibrarynamespace = {};};
if (!mylibrarynamespace.registerStartupScript) mylibrarynamespace.registerStartupScript = function (fn) {
/* create local pointer for added function */
var f = fn;
/* create pointer to existing pageLoad function */
var pLoad = pageLoad;
/* add new function pointer to pageLoad by creating new anonymous function (search Google for "javascript enclosures" for why pl and f will persist with this newly defined anonymous function) */
pageLoad = function (sender, args) {
pLoad(sender,args);
f(sender, args);
}
}
然后,要在客户端代码中的任何位置使用它,只需执行以下操作:
mylibrarynamespace.registerStartupScript(
function (sender, args){
/* do my AJAX always enabled startup code logic here*/
}
);
为了更容易地更改功能,我建议传入的匿名函数调用该页面中的函数或控件的库子集,这样您只需要更改库的函数声明(在文件中或在运行时动态) )更改网站特定部分的pageLoad的工作方式。
答案 2 :(得分:3)
我相信如果你在脚本块上面添加(或移动)ScriptManager控件,你就不需要将它包装在jQuery的$(document).ready()
函数中。通过这样做,Sys
显然可以作为ScriptManager:
注入了大量的JavaScript 确切的位置 ScriptManager控件位于 在页面中。 [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]
然而,这个解决方案仍然可能让你感到胃灼热,因为对于任何毫无戒心的开发人员来说,ScriptManager实际上在这里提供的内容肯定不是很明显。
在ScriptManager中添加脚本引用的另一种方法(参见上面链接文章中讨论的“更好的方法”)并不适合我,因为我不是整个ScriptManager方法的忠实粉丝。 / p>
答案 3 :(得分:0)
尝试使用ScriptManager注册客户端脚本块,但为每个附加函数调用提供唯一标题,特别是如果它使用相同的函数但具有不同的参数值,则具有唯一参数。如果您使用add_load技术,则只应在页面加载不是回发时使用,即仅在页面刷新或页面加载后调用一次而不回发。
试试这个: ScriptManager.RegisterClientScriptBlock(this,GetType(),&#34;唯一标题&#34;,&#34; alert(&#39; quick test&#39;);&#34;,true);