Web 技术研究所

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

统一innerHTML文本格式

  从元素上获取的HTML通常未必会和原始源中的HTML完全相同。当我们访问innerHTML的时候,得到的HTML是程序生成的。虽然这样得到的内容都是标准的HTML,解析也不会出错,但如果作为解析之外的用途就可能会出问题。有时我们可能要另写程序来统一它。
  比如一个很简单的代码 <script>
onload=function(){alert(document.body.innerHTML);};
</script>
<body>
<div class="class"    id="id" a="a" b="b" c="c" x="x">
  <br/>
</div>
</body>


  第一张截图是来自IE8的,它让标签名全都使用大写字母,属性的顺序也是乱的,甚至对于一些内置属性都不带引号的,对于的空格也会被吞掉,还有自结束标签最后的斜杠也会吞掉。低版本IE中得到的innerHTML乱得简直难以阅读!第二张Chrome上的截图情况会乐观一些,但对于属性中多余的空格和自结束标签的斜杠也依然会被吞掉。总之,他们都不是原始源。
  我们可以用正则表达式来匹配这些HTML属性,并统一它的样式。但对于低版本IE吞掉空格的情况要怎么办呢?其实并不是所有时候都会吞空格的,空格有时候也对布局产生影响,比如white-space属性为pre的时候。于是我们可以给元素赋予这个样式之后再访问innerHTML。但由于CSS渲染是在JavaScript执行完成后才生效的,所以这么做的话获取HTML就无法同步完成了,但这影响并不大。另外我们也不能直接操作文档里的元素,因为添加了这个样式之后页面会发生改变。于是我们创建一个新元素,并把旧节点拷贝过来。
<script>
onload=function(){
  getFormattedHTML(document.body,function(e){
    alert(e);
  });
};
function getFormattedHTML(e,f){
  if(!-[1,]){ //针对低版本IE
    var i,o,div=document.createElement("div");
    div.style.whiteSpace="pre",div.style.display="none";
    document.appendChild(div);
    for(i=0;o=e.childNodes[i];i++)div.appendChild(o.cloneNode(true));
    div.currentStyle.whiteSpace;
  }else var div=e;
  setTimeout(function(){
    var html=div.innerHTML;
    if(!-[1,])document.removeChild(div);
    f(html.replace(/<((?:"[^"]*"|[^>])+)>/g,function($,e){
      e=e.match(/(?:"[^"]*"|\S)+/g);
      e.tag=e.shift().toLowerCase();
      for(var i=0;i<e.length;i++)
        e[i]=e[i].split("="),
        e[i]=[e[i].shift().toLowerCase(),e[i].join("=")],
        e[i][1]=(e[i][1]||e[i][0]).replace(/^(?!").*/,'"$&"'),
        e[i]=e[i].join("=");
      e.sort(); //对属性排序
      if(e.length)e.unshift("");
      return "<"+e.tag+e.join(" ")+">";
    }));
  });
};
</script>
<body>
<div class="class" id="id" a="a" b="b" c="c" x="x">
  <input type="checkbox" checked="checked" />
  <br/>       a - b - c
</div>
</body>

  这个例子在IE8上测试就保留下了文本中的换行和空,并且我们还对属性做了排序。当然上面的代码只是随手写的,也许还有很多情况没考虑到,我只提供一个思路,具体的解决方法可能更复杂。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^