【问题标题】:Why not use Javascript handlers on the body element?为什么不在 body 元素上使用 Javascript 处理程序?
【发布时间】:2011-02-13 07:25:10
【问题描述】:

作为'How do you automatically set the focus to a textbox when a web page loads?'问题的答案,Espo建议使用

<body onLoad="document.getElementById('<id>').focus();">

Ben Scheirmanreplies(无需进一步解释):

任何 Javascript 书籍都会告诉你不是 将处理程序放在 body 元素上 像这样

为什么这会被认为是不好的做法?在 Espos 的回答中,说明了一个“覆盖”问题。这是唯一的原因,还是有其他问题?兼容性问题?

【问题讨论】:

    标签: javascript html dom-events handler onload


    【解决方案1】:

    我想这也与其他 javascript 文件有关。如果您的某些 javascript 文件包含用于 body onload 的处理程序,并且如果您在页面中提供了内联 body onload 处理程序,则脚本内的处理程序将不会被执行。

    【讨论】:

      【解决方案2】:

      使用onLoad 变得越来越少,因为无法使用此方法堆叠回调,即新的onload 定义覆盖旧的定义。

      在 jQuery 及其.load() 等现代框架中,回调可以堆叠,并且在同一页面上使用不同的脚本、插件等时不会发生冲突。

      此外,将标记与代码分开被广泛认为是一种很好的做法,因此即使您想使用onload(如果您控制完整的环境并知道自己在做什么,这完全可以)可以在 head 或单独的 JavaScript 文件中将该事件附加到脚本端:

      window.onload = function() { document.getElementById...... }
      

      【讨论】:

      • @Pekka 如果 body 尚未加载,document.body.onload 如何工作?
      • @system 不确定您的意思?
      • @Pekka 我的意思是,如果您将 document.body.onload 放在标题中,如果正文尚未加载,它如何工作?
      • @systempunto 如果您将 document.body.onload 放在标题中,则在加载正文(包括图像和样式表)时将执行您放入事件的任何内容。您可以随时分配事件,在这种情况下,您甚至必须在加载主体之前分配它,否则它永远不会触发。这是否符合您的意思?
      • 如果我将 document.body.onload 放在标题中,我会在 FF 3.6.5 上得到“document.body is null”
      【解决方案3】:

      好吧,如果你问我,'&lt;id&gt;' 是一个无效的 id 值。我不会使用这样的字符。

      为了获得良好的实践,最好使用 window.onload IMO 并将其放在 &lt;head&gt; 标记中。或者更好的是,您可以将其移动到 .js 文件并缓存它以提高速度。

      【讨论】:

        【解决方案4】:

        作为一个更非 javascript 相关的答案,您的应用程序的表示层可以是模板的形式,甚至可以是嵌套模板(dreamweaver 或 Master Pages 等),其中可能不需要在 body 标记中包含特定代码或冲突模板“继承”时需要其他代码

        【讨论】:

          【解决方案5】:

          除了可能的稍后覆盖之外,我看不出其他原因,这将导致您的代码永远不会被执行。此外,突兀的 javascript 不再受到高度重视。

          您应该分配一个监听事件的函数。你可以这样做:

          function onloadFocus() {
              document.getElementById('<id>').focus();
          }
          
          if (window.addEventListener) {      
              window.addEventListener('load', function(e) {onloadFocus();}, false);} 
          else if (window.attachEvent) {
              window.attachEvent('onload', function(e) {onloadFocus();}); 
          }
          

          ...或依赖一个 javascript 框架,例如 jquery,它可以为您提供相同的功能。

          【讨论】:

            【解决方案6】:

            &lt;body&gt; 元素中使用onload 属性没有任何问题,前提是:

            • 您可以完全控制页面
            • 您当前在页面上使用或将来可能拥有的任何其他脚本都不会尝试在 body 元素或 window 对象上设置 onload 处理程序
            • 您了解自己的想法,并乐于在您的标记中添加一小段脚本。

            还值得注意的是,&lt;body onload="..."&gt; 是正式标准 (HTML 4) 的一部分,而 window.onload 不是,尽管它在多年前已在所有主要浏览器中实现。

            【讨论】:

            • 事实上,传统上没有 window 对象被正式标准化。现在正在修复这个问题:HTML5 standardises这部分浏览器对象模型,包括onload
            【解决方案7】:

            暂时不考虑内联事件处理程序属性是否错误的问题,onload 事件不适合放置自动对焦器,因为它仅在加载整个页面(包括图像)时触发。

            这意味着用户将不得不等待更长时间才能发生自动对焦,如果页面需要很长时间才能加载,他们可能已经将注意力集中在浏览器页面的其他位置(或 chrome,例如地址栏),只有在打字中途发现他们的注意力被偷了。这很烦人。

            自动对焦是一种潜在的敌对功能,应谨慎而礼貌地使用。其中一部分是减少聚焦前的延迟,最简单的方法是直接在元素本身之后添加一个脚本块。

            <input id="x">
            <script type="text/javascript">
                document.getElementById('x').focus();
            </script>
            

            【讨论】:

            • 很高兴你提到了这个事实。这是我从很多用户那里得到的功能请求。我不知道这是否与他们的经验水平低有关,而且坦率地说,我不知道 js 技巧有什么好的替代方案。如果浏览器可以选择将注意力集中在 tabindex 最低的元素上,那就太好了,更有经验的用户可以选择退出。我个人觉得很烦人,但不知道如何找到好的中道。
            • 也许可以实现“焦点跟随凝视”,因为这似乎是我的用户想要的:)
            • +1。完全同意,我考虑过提出这一点,但在写完onload 问题后就失去了热情。
            【解决方案8】:

            查看它的另一种方法是使用addEventListener 而不是将其用作 html 代码尝试 JS:

            <body onLoad="document.getElementById('<id>').focus();">
            
                <body>
            
                <script>
            
                 document.body.addEventListener('load', funcLoad);
            
                 function funcLoad(){
            
                 document.getElementById('<id>').focus();
            
                }
            
                </script>
            </body>
            

            试试吧,它可能比其他解决方案效果更好。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-03-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-12-28
              • 2011-02-21
              • 2014-02-07
              相关资源
              最近更新 更多