Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

IE8的innerHTML BUG修复

  之前的文章中有介绍过一个IE处理innerHTML的BUG。当对元素设置innerHTML时,元素的所有后代节点会被全部断开关联,而不是只有目标元素的子节点受影响。这个特性可以通过removeChild来修复,我们现在要做的是把这个修复直接封装起来实现。
  下面是测试代码
<script src="ie-innerHTML.js"></script>
<script>
onload=function(){
  var div=document.createElement("div");
  document.body.appendChild(div);
  div.innerHTML="<span><a></a></span>";
  var span=div.children[0];
  console.log(span.children.length);
  div.innerHTML='<font color="red">a</font>';
  console.log(span.children.length);
  console.log(div.innerHTML);
};
</script>
  下面是针对IE的修复代码
<script>
//ie-innerHTML.js
if(/MSIE|Trident/.test(navigator.userAgent))
(function(){
  if(window.HTMLElement)tags=[HTMLElement.prototype];
  else {
    var tags=[
      "Unknown","UList","Title","TextArea","TableSection","TableRow",
      "Table","TableCol","TableCell","TableCaption","Style","Span",
      "Select","Script","Param","Paragraph","Option","Object","OList",
      "Meta","Marquee","Map","Link","Legend","Label","LI","Input",
      "Image","IFrame","Html","Heading","Head","HR","FrameSet",
      "Frame","Form","Font","FieldSet","Embed","Div","DList",
      "Button","Body","Base","BR","Area","Anchor"
    ],html5tags=[
      "abbr","article","aside","audio","canvas","datalist","details",
      "dialog","eventsource","figure","footer","header","hgroup","mark",
      "menu","meter","nav","output","progress","section","time","video"
    ];
    for(var o,n,i=0;o=window["HTML"+tags[i]+"Element"];i++)
      tags[i]=o.prototype;
    for(i=0;i<html5tags.length;i++)
      tags.push(
        document.createElement(html5tags[i]).constructor.prototype
      );
  };
  var properties={
    innerHTML:{
      set:function(data){
        while(this.lastChild)this.removeChild(this.lastChild);
        this.insertAdjacentHTML("afterbegin",data);
      },get:function(){
        return this.outerHTML.replace(/^\s*<[^>]+?>|<[^>]+?>\s*$/g,"");
      }
    }
  };
  for(i=0;o=tags[i];i++)
    for(n in properties)Object.defineProperty(o,n,properties[n]);
})();
</script>

  在IE8+上,使用Object.defineProperty,重新定义innerHTML方法,让它在set时先对元素做一次removeChild。但是由于innerHTML这个方法被覆写了,所以对HTML的读写需要寻找其它方法。比如上面的代码中,写入HTML使用了insertAdjacentHTML,读取HTML使用了outerHTML删除掉外层标签的方式。这些只是比较简单的方法,也许有更厉害的方法来解决这些问题,我就懒得研究了。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^