【问题标题】:Sys.Application.add_load() vs. $(document).ready() vs. pageLoad()Sys.Application.add_load() 与 $(document).ready() 与 pageLoad()
【发布时间】:2011-04-07 12:25:47
【问题描述】:

我的页面有一些需要在页面加载时运行的 javascript。所说的 javascript 需要定位 ServerControl 的客户端组件,它使用 $find() 来完成。

当然,如果我将代码直接发送到页面上,它会在页面被读取时执行,并且会失败,因为它所依赖的任何内容尚未初始化。

如果我将代码放在 pageLoad() 函数中,它运行得很好,因为 asp.net 会自动为任何名为 pageLoad() 的函数连接一个 onload 处理程序。问题是我真的不喜欢 pageLoad() 解决方案——主要是因为它是一个单一的全局名称。如果我使用 pageLoad() 提交一些代码,我只知道其他一些程序员会在不合适的地方复制该方法,我们最终会得到一个包含两个或多个不同 pageLoad() 函数的页面,并且结果将是一堆神秘的错误,需要永远追查。

所以,我将我的代码放在传递给 jquery 的 $(document).ready() 的匿名函数中。这会失败,因为它在 ServerControl 的客户端组件存在之前运行。

所以,我将我的代码放在一个由 Sys.Application.add_load() 传递给的匿名函数中。这也失败了,因为 Sys 未定义。

所以我最终决定将我的代码放入 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>

必须有更好的方法来处理这个问题。

有什么想法吗?

【问题讨论】:

    标签: asp.net-ajax


    【解决方案1】:

    如果您可以控制代码隐藏,则可以通过以下方式注册 JavaScript 以在启动时运行:

    this.Page.ClientScript.RegisterStartupScript(
        this.GetType(), 
        "StartupScript", 
        "Sys.Application.add_load(function() { functioncall(); });", 
        true);
    

    只要您的组件已通过 Sys.Application.add_init() 加载,您应该没问题...

    【讨论】:

      【解决方案2】:

      我想为那些尝试构建外部库并尝试在 .NET 中尽可能遵循不显眼的 javascript 思维方式的人提供一种替代方案。

      pageLoad 是一种很好的自动连接 AJAX 事件的方法,这些事件应该在每次页面加载时触发(无论该加载来自到此页面的后退按钮导航、到页面的前进按钮导航、AJAX 回调还是标准页面load 等),并且由于您不必担心等待 ScriptManager 存在于 DOM 中,并且它的命名方式在很大程度上是有意义的(pageLoad 与 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 的工作方式。

      【讨论】:

      • 在 javascript 中像这样写你的前几行更符合规范:var pageload = pageload ||功能(发件人,参数){};
      【解决方案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 方法的忠实粉丝。

      【讨论】:

        【解决方案4】:

        尝试使用 ScriptManager 注册客户端脚本块,但为每个附加函数调用提供唯一的标题,特别是如果它具有唯一的参数,如果您使用相同的函数但具有不同的参数值。如果您使用 add_load 技术,则仅应在页面加载不是回发时使用,即仅在页面刷新或页面加载后调用一次而没有回发。

        试试这个: ScriptManager.RegisterClientScriptBlock(this, GetType(), "唯一标题", "alert('快速测试');", true);

        【讨论】:

          猜你喜欢
          • 2011-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-20
          • 1970-01-01
          • 1970-01-01
          • 2011-03-26
          相关资源
          最近更新 更多