【问题标题】:What are the common mistakes to avoid when coding javascript for Internet Explorer?为 Internet Explorer 编写 javascript 时应避免哪些常见错误?
【发布时间】:2018-02-20 14:50:34
【问题描述】:

我即将开始编写一个新的、大量使用 javascript 的网站,但在开始之前,我想通过事先了解其中的怪癖来最大限度地减少我在 Internet Explorer 中的调试时间。我不打算过多担心 IE6。

在其他浏览器中运行良好但在 Internet Explorer 中中断的 javascript 代码中应避免哪些常见错误/差异?

【问题讨论】:

  • 这是一个很好的“社区维基”候选人。
  • 今天再一次,当我认为这是一个非常真正的问题时,人们又将其作为“不是一个真正的问题”来结束。这是为什么呢?
  • @patrick:因为在最初的几分钟内,两个投票最高的答案包含了废话。显然,他们选择投赞成票而不是投反对票。
  • @BalusC - 那太不幸了。

标签: javascript internet-explorer


【解决方案1】:

如果您直接通过 javascript 分配事件处理程序,event不会自动提供。

myElement.onclick = function(e) {
    alert(typeof e); // undefined
}

解决方法是拉window.event

myElement.onclick = function(e) {
    e = e || window.event;
    alert(typeof e); // this is ok now
}

如果您是直接在元素上的事件处理程序,则可以手动提供 event 引用。

<input type="text" onclick="myMethod(event);"></input>

这是跨浏览器,没问题,如果你必须走那条路。

使用attachEvent 设置事件处理程序会自动将event 对象作为参数提供给方法。

【讨论】:

    【解决方案2】:

    这是一个微妙的问题:如果您的网站有多个框架(或 iframe),并且您有时会在框架之间进行 Javascript 代码通信,那么 IE(6 和 7,不太确定 8 和 9)对Javascript 对象的“血统”,即使是没有任何 DOM 引用的对象。这意味着,如果您将几乎任何类型的 Javascript 对象(字符串和数字通常都可以,但即使是 Date 实例在过去也给我带来了问题)从一帧到另一帧,如果在稍后的某个时间 源框架更新为一个新页面,如果目标页面试图与该通信对象混淆,它将获得异常。 Firefox 对这类事情非常温和,但是当 IE 垃圾收集旧页面时,它不喜欢引用该页面创建的 Javascript 对象。

    【讨论】:

      【解决方案3】:

      IE(8 及以下,不确定 9)无法处理访问字符串等数组中的字符,如:

      var str = 'abc';
      var c = str[2];
      alert(c)
      

      在大多数浏览器中,这会提示“c”,但 IE 会提示“未定义”。出于跨浏览器的原因,应该使用 charAt 函数:

      var str = 'abc';
      var c = str.charAt(2);
      alert(c)
      

      这也会在 IE 中提醒“c”。

      另一个小区别是对象和数组中的尾随逗号。这在大多数浏览器中都有效,但在 IE 中会引发错误:

      ar = [1,2,3,]
      

      还有

      ob = {name:'janet', surname:'walker',}

      如果你不知道这可能会很烦人。这两个问题可能是我经常遇到的问题,因为我习惯了python,但仍然值得关注。

      【讨论】:

      • 无论如何这都是非标准行为,因此 IE 完全有权不支持它。
      【解决方案4】:

      用 + 连接字符串

      var str="";
      for (var i = 0; i < max; ++i) {
        str += somefunction(i);
      }
      

      在 MSIE 上可能需要几分钟时间。我曾经做过一个测试,其中 Opera 和 Firefox 在几秒钟后完成,但 MSIE 在 20 分钟后还没有完成!

      但是,如果使用数组,MSIE 很快:

      var str = [];
      for (var i = 0; i < max; ++i) {
         str.push( somefunction(i));
      }
      str = str.join("");
      

      抱歉,目前找不到我发布的相关帖子。

      【讨论】:

        【解决方案5】:

        IE 的 JS 引擎在 IE9 之前是。真的,真的很慢。比 Mozilla 和 Webkit 实现慢数百到数千倍。

        这显示在动画计时器的最小分辨率、完成排序的时间和(正如@some 指出的)虚假字符串连接,以及您的网站性能受 JS 引擎本身速度限制的任何其他地方。

        【讨论】:

        • 计时器分辨率问题似乎是内部实现的问题,而不是 js 引擎速度慢。 ejohn.org/blog/accuracy-of-javascript-time
        • 点了 - 但这仍然是一个 JS 引擎实现决策,导致 IE8 感觉迟缓。
        【解决方案6】:

        请注意 Internet Explorer 如何处理 dom 树解析和导航,特别是在解析 httpObjects 时通常也存在这一点:

        • xmlNode.textContent 在 Internet Explorer 中不返回任何内容
        • 必须使用xmlNode.firstChild.nodeValue 或返回节点值的东西

        -

        【讨论】:

          【解决方案7】:

          Internet Explorer。

          好吧,更严重的是,另一个答案中的尾随逗号答案很好。使用框架会有所帮助,但它不是包罗万象的。您将不得不处理跨浏览器问题。因此,请确保在您关心的所有版本中进行测试。

          【讨论】:

          • 嘿。我通常不会 +1 像这样的答案,因为它们并没有那么有帮助,但是……如果我大声笑的话,那就去吧。 (IE 一直是我最近从事的一个项目的压力来源。)
          • 这个原始答案(一个单一的“Internet Explorer”)已经杀死了整个问题,它本身并没有那么糟糕。
          【解决方案8】:

          IE 不支持自定义事件,仅支持 DOM 事件(即使在 9 beta 中也是如此)。

          【讨论】:

            【解决方案9】:

            在编写必须支持 IE 的网站时,最常见的错误是忘记在每个版本中进行测试。

            您需要确保您的所有代码都可以在 IE6(如果您计划支持它)、IE7、IE8 和 IE8-in-IE7-mode 中运行。还有 IE9(现在处于测试阶段)。

            测试多个 IE 版本的捷径很少,但请注意,它们并不总是提供与真实用户看到的完全相同的结果;唯一可以确定的方法是在真实版本的 IE 中对其进行实际测试,无论这有多痛苦。

            【讨论】:

            • 确实如此 - 但 Internet Explorer 的错误通常会通知您“第 0 行错误”,然后您必须为每个版本安装调试器或事先知道IE 和其他浏览器之间的哪种差异会导致这种情况。
            【解决方案10】:

            注意处理 iframe 边框的方式等细微差别 (How to Remove an IFrame border in Javascript)。

            我想internet-explorer tag 应该会给你很多很好的例子。

            【讨论】:

              【解决方案11】:

              如果你想测量某件事需要多长时间,你应该知道时间的分辨率在 IE 中只有 15ms 左右,而在 FF、Chrome 和 Opera 中是 1ms。

              您可以使用以下代码自行测试:

              var end,start = new Date().getTime(); //Gets number of milliseconds since epoch
              while( (end = new Date().getTime() ) === start); //Wait for the time to change
              alert(end-start); // Shows 1 in FF, Chrome and Opera, but 15 or 16 in MSIE
              

              多年来一直如此,仍然适用于 MSIE8,但不是常识。 lincolnk 链接到 a blog post by John Resig 从 2008 年 11 月 12 日在上面的评论中。当我读到这篇文章时,我忍不住微微一笑,因为我已经知道很多年了,早在 Netscape 还是普通浏览器的时候。

              当我想到它时,我有一个非常微弱的记忆,Netscape 从一开始也有低分辨率,可能是通过读取每秒更新 18.2 次的系统时间,但后来改变了它,它给出了 1ms 分辨率的时间.然而,由于这应该发生在大约 15 年前,我不确定它是否正确,我不会试图证明它。

              为了便于阅读,我在上面使用 getTime 而不是一元运算符

              【讨论】:

                【解决方案12】:

                除非打开控制台窗口,否则 IE 7/8 无法理解 console.log/dir。如果您将任何 JS 留在 prod 环境中,这很容易破坏您的 JS。一直都有

                if(window.console)
                   console.log('Hello World')
                

                【讨论】:

                  【解决方案13】:

                  使用jQueryPrototype 之类的框架,您无需担心。

                  编辑:

                  我应该澄清一下。你会少很多担心。如:

                  • ActiveXObject 与 XMLHttpRequest
                  • attachEvent 与 addEventListener

                  列表项-

                  【讨论】:

                  • 为此 +1。这些库是专门设计的,因此您不必担心浏览器实现之间的所有兼容性和差异。给@Herman 的好建议。
                  • 不正确。您仍然需要担心对象的创建、数组末尾是否有逗号、换行符后的括号......诸如此类的事情。
                  • @annakata -- jquery 在 xml 解析中对我来说失败了。见stackoverflow.com/questions/3513919/jquery-and-xml-issue
                  • @hvgotcodes:jQuery 通过将 XML 字符串分配为元素的 innerHTML 来假装 XML 是 HTML。这不可靠:请参阅此问题 stackoverflow.com/questions/2908899/… 以及 jQuery 文档:api.jquery.com/jQuery/#jQuery2
                  • 您可以使用 jQuery 获取 XML DOM 中的数据(来自 XMLHttpRequest#responseXML)。您不能为 jQuery 提供一串 XML 标记并期望它从中生成一个可行的 XML DOM,因为它所做的只是将您的字符串写入innerHTML。奇怪的是,这么多人似乎认为这应该可行。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-02
                  • 2013-04-28
                  • 2018-11-29
                  • 2012-02-09
                  • 1970-01-01
                  • 2016-08-21
                  相关资源
                  最近更新 更多