I developed some javascript enhanced pages that run fine on recent Firefox and Safari. I missed to check in Internet Explorer, and now I find the pages don't work on IE 6 and 7 (so far). The scripts are somehow not executed, the pages show as if javascript wasn't there, although some javascript is executed. I am using own libraries with dom manipulation, from YUI 2 I use YUI-Loader and the XML-Http-Request, and on one page I use "psupload", which depends on JQuery.

I am installing Microsoft Script Editor from Office XP and will now debug. I will also write specific tests now.

IE的典型缺点是什么?我可以朝哪个方向睁大眼睛.

I found this page, which shows some differences. visit: Quirksmode

Can you from your experience name some typical things I should look for first?

稍后我还会问更多关于特定任务的问题,但现在我对你的经验感兴趣,为什么IE在Firefox中运行良好的脚本上通常失败

Edit:谢谢你那些精彩的回答!

同时,我对整个代码进行了修改,这样它也可以与Internet Explorer一起使用.我集成了jQuery,并在其上构建了自己的类.这是我的基本错误,我没有从一开始就在jQuery上构建所有的东西.现在我有了.

JSLint也帮了我很多.

来自不同答案的许多单一问题都起到了帮助作用.

推荐答案

如果您发现任何错误/遗漏等,请随时更新此列表.

Note: IE9修复了以下许多问题,因此很多问题只适用于IE8及以下版本,在一定程度上IE9处于怪癖模式.例如,IE9本机支持SVG、<canvas><audio><video>,但是必须enable standards compliance mode才能使用它们.


##一般信息:

  • Problems with partially loaded documents: It’s a good idea to add your JavaScript in a window.onload or similar event as IE doesn’t support many operations in partially loaded documents.

  • Differing attributes:在CSS中,IE是elm.style.styleFloat,Firefox是elm.style.cssFloat.在<label>个标签中,for属性在IE中用elm.htmlFor访问,而在Firefox中用elm.for访问.请注意,IE中保留了for,因此elm['for']可能是阻止IE引发异常的更好方法.


##Base JavaScript language:

  • Access characters in strings: 'string'[0] isn’t supported in IE as it’s not in the original JavaScript specifications. Use 'string'.charAt(0) or 'string'.split('')[0] noting that accessing items in arrays is significantly faster than using charAt with strings in IE (though there's some initial overhead when split is first called.)

  • IE中不允许Commas before the end of objects:例如{'foo': 'bar',}.


##要素具体问题:

  • Getting the document of an IFrame:

    • Firefox and IE8+: IFrame.contentDocument(IE开始支持此from version 8.)
    • IE: IFrame.contentWindow.document
    • (IFrame.contentWindow refers to the window in both browsers.)

  • Canvas: Versions of IE before IE9 don't support the <canvas> element. IE does support VML which is a similar technology however, and explorercanvas can provide an in-place wrapper for <canvas> elements for many operations. Be aware that IE8 in standards compliance mode is many times slower and has many more glitches than when in quirks mode when using VML.

  • SVG: IE9本机支持SVG.IE6-8可以支持SVG,但只有external plugins个支持JavaScript操作的插件.

  • <audio> and <video>: are only supported in IE9.

  • Dynamically creating radio buttons: IE<;8有一个错误,使得用document.createElement创建的单选按钮不可选中.另请参见How do you dynamically create a radio button in Javascript that works in all browsers?,了解解决此问题的方法.

  • Embedded JavaScript in 101 tags and 102 conflicts in IE:如果a标记的href部分(例如<a href="javascript: doStuff()">)中嵌入了JavaScript,IE将始终显示onbeforeunload返回的消息,除非事先移除onbeforeunload处理程序.另请参见Ask for confirm when closing a tab.

  • <script> tag event differences: onsuccess and onerror aren't supported in IE and are replaced by an IE-specific onreadystatechange which is fired regardless of whether the download succeeded or failed. See also JavaScript Madness for more info.


##元素大小/位置/滚动和鼠标位置:

  • Getting element size/position:在IE中,元素的宽度/高度有时是elm.style.pixelHeight/Width而不是elm.offsetHeight/Width,但在IE中两者都不可靠,尤其是在"怪癖"模式下,有时一个比另一个效果更好.

elm.offsetTop and elm.offsetLeft are often incorrectly reported, leading to finding positions of elements being incorrect, which is why popup elements etc are a few pixels off in a lot of cases.

还要注意的是,如果一个元素(或该元素的父元素)的值为displaynone,那么IE在访问大小/位置属性时会引发异常,而不是像Firefox那样返回0.

  • Get the screen size(获取屏幕的可视区域):

    • Firefox: window.innerWidth/innerHeight
    • IE standards mode: document.documentElement.clientWidth/clientHeight
    • IE quirks mode: document.body.clientWidth/clientHeight

  • Document scroll position/mouse position: This one is actually not defined by the w3c so is non-standard even in Firefox. To find the scrollLeft/scrollTop of the document:

    • Firefox and IE in quirks mode: document.body.scrollLeft/scrollTop

    • IE in standards mode: document.documentElement.scrollLeft/scrollTop

    • NOTE:其他一些浏览器也使用pageXOffset/pageYOffset.

        function getDocScrollPos() {
         var x = document.body.scrollLeft ||
                 document.documentElement.scrollLeft ||
                 window.pageXOffset || 0,
             y = document.body.scrollTop ||
                 document.documentElement.scrollTop ||
                 window.pageYOffset || 0;
         return [x, y];
        };
      

    为了获得鼠标光标的位置,mousemove事件中的evt.clientXevt.clientY将给出相对于文档without adding the scroll position的位置,因此需要结合前面的函数:

     var mousepos = [0, 0];
     document.onmousemove = function(evt) {
      evt = evt || window.event;
      if (typeof evt.pageX != 'undefined') {
       // Firefox support
       mousepos = [evt.pageX, evt.pageY];
      } else {
       // IE support
       var scrollpos = getDocScrollPos();
       mousepos = [evt.clientX+scrollpos[0], evt.clientY+scrollpos[1]];
      };
     };
    

## Select /范围:


##Getting elements by ID:

  • document.getElementById还可以在表单中引用name属性(取决于文档中首先定义的属性),因此最好不要使用具有相同nameid的不同元素.这可以追溯到id不是w3c标准的时代.document.all(a proprietary IE-specific property)比document.getElementById快得多,但它还有其他问题,因为它总是将name置于id之前.我个人使用了这段代码,并进行了额外的判断,以确保:

     function getById(id) {
      var e;
      if (document.all) {
       e = document.all[id];
       if (e && e.tagName && e.id === id) {
        return e;
       };
      };
      e = document.getElementById(id);
      if (e && e.id === id) {
       return e;
      } else if (!e) {
       return null;
      } else {
       throw 'Element found by "name" instead of "id": ' + id;
      };
     };
    

##Problems with read only innerHTML:

  • IE不需要设置colcolGroupframeSethtmlheadstyletabletBodytFoottHeadtitletr个元素的innerHTML.下面是一个与表相关的元素相关的函数:

     function setHTML(elm, html) {
      // Try innerHTML first
      try {
       elm.innerHTML = html;
      } catch (exc) {
       function getElm(html) {
        // Create a new element and return the first child
        var e = document.createElement('div');
        e.innerHTML = html;
        return e.firstChild;
       };
       function replace(elms) {
        // Remove the old elements from 'elm'
        while (elm.children.length) {
         elm.removeChild(elm.firstChild);
        }
        // Add the new elements from 'elms' to 'elm'
        for (var x=0; x<elms.children.length; x++) {
         elm.appendChild(elms.children[x]);
        };
       };
       // IE 6-8 don't support setting innerHTML for
       // TABLE, TBODY, TFOOT, THEAD, and TR directly
       var tn = elm.tagName.toLowerCase();
       if (tn === 'table') {
        replace(getElm('<table>' + html + '</table>'));
       } else if (['tbody', 'tfoot', 'thead'].indexOf(tn) != -1) {
        replace(getElm('<table><tbody>' + html + '</tbody></table>').firstChild);
       } else if (tn === 'tr') {
        replace(getElm('<table><tbody><tr>' + html + '</tr></tbody></table>').firstChild.firstChild);
       } else {
        throw exc;
       };
      };
     };
    

    Also note that IE requires adding a <tbody> to a <table> before appending <tr>s to that <tbody> element when creating using document.createElement, for example:

     var table = document.createElement('table');
     var tbody = document.createElement('tbody');
     var tr = document.createElement('tr');
     var td = document.createElement('td');
     table.appendChild(tbody);
     tbody.appendChild(tr);
     tr.appendChild(td);
     // and so on
    

##Event differences:

  • Getting the event variable: DOM events aren't passed to functions in IE and are accessible as window.event. One common way of getting the event is to use e.g.
    elm.onmouseover = function(evt) {evt = evt||window.event}
    which defaults to window.event if evt is undefined.

  • Key event code differences:个关键事件代码差异很大,但如果你看QuirksmodeJavaScript Madness,这几乎不是IE特有的,Safari和Opera又不同了

  • Mouse event differences: IE中的button属性是位标志,它允许同时使用多个鼠标按钮:

    • Left: 1 (var isLeft = evt.button & 1)
    • Right: 2 (var isRight = evt.button & 2)
    • Center: 4 (var isCenter = evt.button & 4)

    The W3C model (supported by Firefox) is less flexible than the IE model is, with only a single button allowed at once with left as 0, right as 2 and center as 1. Note that, as Peter-Paul Koch mentions, this is very counter-intuitive, as 0 usually means 'no button'.

    offsetX and offsetY are problematic and it's probably best to avoid them in IE. A more reliable way to get the offsetX and offsetY in IE would be to get the position of the relatively positioned element and subtract it from clientX and clientY.

    Also note that in IE to get a double click in a click event you'd need to register both a click and dblclick event to a function. Firefox fires click as well as dblclick when double clicking, so IE-specific detection is needed to have the same behaviour.

  • Differences in the event handling model:专有IE模型和Firefox模型都支持自下而上处理事件,例如,如果<div><span></span></div>的两个元素中都有事件,那么事件将在span thendiv中触发,而不是使用传统元素(例如elm.onclick = function(evt) {})时它们绑定的顺序.

    "Capture" events are generally only supported in Firefox etc, which will trigger the div then the span events in a top down order. IE has elm.setCapture() and elm.releaseCapture() for redirecting mouse events from the document to the element (elm in this case) before processing other events, but they have a number of performance and other issues so should probably be avoided.

    • Firefox:

      Attach: elm.addEventListener(type, listener, useCapture [true/false])
      Detach: elm.removeEventListener(type, listener, useCapture)
      (type is e.g. 'mouseover' without the on)

    • IE: Only a single event of a given type on an element can be added in IE - an exception is raised if more than one event of the same type is added. Also note that the this refers to window rather than the bound element in event functions (so is less useful):

      Attach: elm.attachEvent(sEvent, fpNotify)
      Detach: elm.detachEvent(sEvent, fpNotify)
      (sEvent is e.g. 'onmouseover')

  • Event attribute differences:

    • Stop events from being processed by any other listening functions:

      Firefox: evt.stopPropagation()
      IE: evt.cancelBubble = true

    • Stop e.g. key events from inserting characters or stopping checkboxes from getting checked:

      Firefox: evt.preventDefault()
      IE: evt.returnValue = false
      Note: Just returning false in keydown, keypress, mousedown, mouseup, click and reset will also prevent default.

    • Get the element which triggered the event:

      Firefox: evt.target
      IE: evt.srcElement

    • 如果是onmouseout事件,IE中的Getting the element the mouse cursor moved away from: evt.fromElement在Firefox中是evt.target,否则是evt.relatedTarget

    • 如果是onmouseout事件,IE中的Getting the element the mouse cursor moved to: evt.toElement在Firefox中是evt.relatedTarget,否则是evt.target

    • Note: evt.currentTarget(事件绑定到的元素)在IE中没有类似功能

Jquery相关问答推荐

如何在光滑的轮播上添加进度条

如何使 Bootstrap 轮播滑块使用移动左/右滑动

可以推迟 jQuery 的加载吗?

为什么在 jQuery 插件中返回 this.each(function())?

无限滚动jQuery插件

为什么我的 toFixed() 函数不起作用?

如何使用 jQuery Select 所有复选框?

jQuery.parseJSON 单引号与双引号

jQuery增量读取AJAX流?

未捕获的类型错误:$.post 不是函数

javascript中的描述关键字

使用跨域帖子发送凭据?

AngularJS + JQuery:如何在 angularjs 中获取动态内容

在 HTML 表单提交上制作 Enter 键而不是激活按钮

如何将数组传递给 jQuery .data() 属性

是否可以在 beforeunload 弹出窗口中显示自定义消息?

Javascript 将 Markdown/Textile 转换为 HTML(理想情况下,返回 Markdown/Textile)

如何让 JavaScript/jQuery Intellisense 在 Visual Studio 2008 中工作?

如何确定滚动高度?

catch forEach 最后一次迭代