基础
IE67中通过for in 是无法遍历出valueOf和toString属性名。
[].slice.call在IE67下无法在HTMLCollection或者NodeList子类的对象上操作,需要兼容处理。
typeof 判断为"function"时可能为FF下的document.createElement('embed'),有陷阱;
typeof 判断为"object"的时候可能为IE678下的window.alert,有陷阱;
instanceof在跨文档比较iframe里的数组实例是否为父窗口的Array的实例时,为false,有陷阱;
旧版本的IE在DOM和BOM下对象的constructro属性是没有暴露出来的。
IE678下window==document但document!=window,可以用来做类型判断的兼容方法。
IE678的数组没有Array.prototype.indexOf方法,需要做兼容。
JS中通过一个中间对象来实现原型的继承,其中使用了apply方法来执行父类的构造函数,另外ES5里还有Object.create方法来创建继承原型。
节点相关
document.getElementById在IE中是不区分表单元素的ID和Name的,兼容处理需要在调用该方法获取后判断id,不等则需要document.all[id]来查找。
document.getElementByTagName在IE下使用*号时候会混入注释节点,并且无法选取Object下的元素,可以通过firstChild和nextSibling来遍历。
document.createElement在IE678中可以直接传入类似innerHTML的字符串HTML,可以用这种方式生成带name属性的input与iframe元素。
IE678下input和iframe元素的name属性是只读的,不能修改。
innerHTML有很多兼容问题,例如IE会去掉没用的空白,再例如IE678用innerHTML生成style、script、link、noscript标签需要在生成标签前加些东西。
innerHTML不会执行script标签里面的脚本,但支持script标签的defer属性的能执行;可以直接通过eval来提取JS执行。
innerHTML插入的有的标签不能单独作为div的子元素,例如td等元素需要外面包装tbody等。
Firefox有个createContextualFragment方法,此外IE有个insertAdjaceHTML方法,最后还有个createDocumentFragment方法,可以高效添加节点。
cloneNode方法在标准浏览器下只会复制元素标签内的属性和通过setAttribute设置的属性,而IE678还会复制通过n.aaa="xxx"设置的属性;
IE还会复制attachEvent绑定的事件,可以使用outerHTML来兼容。
removeChild方法在IE67中有内存泄漏的问题,可以使用innerHTML来干净地清除节点。
setAttribute有时候并不一定生效,例如在IE下使用该方法对iframe进行frameBorder设置为0的操作,因此可以通过niframe.frameBorder=0来兼容。
getAttribute在获取href等属性时,IE67可能会对值进行编码,因此可以设计getAttribute的第二个参数为2就可以返回原始值。
iframe下的跨域可以通过postMessage并监听onmessage事件来实现,IE67中需要通过定时器setInterval以及window.navigator对象的跨域漏洞来兼容。
样式相关
标准浏览器使用opacity:0.4来设置透明度,IE678需要通过filter:alpha(opacity=40)来设置样式。
IE67还需要元素是hasLayout的才能透明。
IE发明了clientXXX的属性,用于获取元素的可视区的尺寸,不包括滚动条和被隐藏的部分。
IE的window.offsetWidth是clientWidth+滚动条+边框;而标准浏览器理解成网页内容实际宽度。
IE的window.scrollWidth是网页的实际内容宽度,可以小于clientWidth;而标准浏览器理解成最小值为clientWidth。
都放一起取最大值就可以了。
元素的绝对坐标可以通过offsetTop和offsetLeft并使用offsetParent来计算。
元素相对于可视区域的坐标可以用getBoundingClientRect来获取,兼容很好。