现在的位置: 首页 > Tools > jQuery > experience > 正文
jQuery的html()函数和原生innerHTML属性比较
2014年02月26日 experience, javascript ⁄ 共 2991字 评论数 1 ⁄ 被围观 11,530 views+
文章目录
[隐藏]

不可否认jQuery是一个很犀利的工具,很容易让人对其产生依赖感。不过好的工具不一定是最适合的解决方案,就跟漂亮的女人并一定适合做你老婆的道理是一样的。本篇文章针对jQuery的html()函数和javascript原生innerHTML属性的优缺点做概要比较。

innerHTML属性的优点

  • innerHTML是w3c制定的行业标准,几乎所有浏览器都做了支持;
  • 作为原生支持,innerHTML在各主流浏览器下的执行效率是很高的;

innerHTML属性的缺点

虽然各个浏览器都实现了innerHTML,但是各个浏览器下innerHTML的行为却有着差异,较为另类的当属IE,IE不同版本表现得也不一样,这样导致innerHTML在IE下,用起来有很多不方便的地方,一个个的说来。

IE6-IE8处理html5标签和属性问题

IE6,IE7,IE8浏览器设置innerHTML属性时会忽略html5属性和标签。IE6-IE8不是不支持html5么?在这些版本IE里设置html5标签有什么意义呢?答案很简单,就算不支持html5的一些效果,至少要让网页的大体布局能够正常显示出来。

解决方案网上有很多资料,也有现成的脚本插件解决这个问题的,主体思路就是利用document.createElement方法创建出html5里的标签来,createElement接口是可以接纳任何标签的,本文不做重复描述了。

IE6-IE7处理href和src属性问题

标准模式下,IE6,IE7设置innerHTML属性时会把href,src属性自动转为绝对路径;在IE的怪异模式(Quirks)下,几乎所有IE版本都会不自觉地转换路劲为绝对路径,看借来的代码:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>  
<html>  
<head>  
    <title></title>  
</head>  
<body>  
<div id="test">  
    <a href="#"> test </a>  
</div>  
<div id="result"></div>  
</body>  
</html>
1
2
3
4
5
6
7
8
(function(){   
    var test = document.getElementById('test');   
    alert(test.innerHTML);// will be '<a href="#"> test </a>'   
 
    var result =  document.getElementById('result');   
    result.innerHTML = test.innerHTML;   
    alert(result.innerHTML)// will be '<a href="http://www.xxx.xxx/xxx.html#"> test </a>' in IE6,IE7 or all IE in Quirks model   
})();

如何解决这个问题呢?在 IE 下使用 getAttribute('href', 2 )方法。 Microsoft 给此方法扩展了第二个参数,可设置为 0、1、2,如果设置为 2 ,则返回属性原始值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(){   
    var test = document.getElementById('test');   
    alert(test.innerHTML);   
    var result =  document.getElementById('result');   
    result.innerHTML = test.innerHTML;   
    if(/*@cc_on!@*/0 ) { //if ie   
        var links1 = test.getElementsByTagName('a');   
        var links2 = result.getElementsByTagName('a');   
        for(var i = 0, len = links1.length; i < len; ++i ) {   
            //利用getAttribute('href', 2)得到的正确值,重新设置href属性   
            links2[i].href = links1[i].getAttribute('href', 2);   
        }   
    }   
    alert(result.innerHTML);   
})();

问题是可以这样折中的解决,但是也付出了代价,重新设置href的代价,要是html字符串特别复杂,势必也会影响到性能。代码和解决方法均取之于怿飞博客的这篇文章,在他的这篇文章中还提到了另外一个跟本文无关的bug,有兴趣的可以去看看。

IE里有些元素的innerHTML是只读的

在IE6,IE7,IE8,IE9里面 colcolGroupframeSethtmlheadstyle,tabletBodytFoottHeadtitle, tr 这几个的innerHTML属性是只读的,不可以赋值,赋值的话就脚本报错。IE10这些标签的innerHTML改成可写的了。

既然在IE6-IE9里这些标签的innerHTML属性是只读的,那么我们尽量避免对这些标签的innerHTML属性赋值,比如说对table的innerHTML可以改为对table父元素(假设是div)的innerHTML属性赋值。

不过有时候我们没办法避免对这些只读属性进行赋值,那么该怎么办呢,网上的解决方案也是一搜一大堆,我们来看看其中一种解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var oTable=document.getElementById("test");   
setTableInnerHTML(oTable,"<tr><td>innerHTML</td></tr>");   
 
function setTableInnerHTML(table, html) {   
    if(navigator && navigator.userAgent.match(/msie/i)){   
        var temp = table.ownerDocument.createElement('div');   
        temp.innerHTML = '<table><tbody>' + html + '</tbody></table>';   
        if(table.tBodies.length == 0){   
            var tbody=document.createElement("tbody");   
            table.appendChild(tbody);   
        }   
        table.replaceChild(temp.firstChild.firstChild, table.tBodies[0]);   
    } else {   
        table.innerHTML=html;   
    }   
}

这段代码是处理table标签的innerHTML属性的,思路是通过创建临时的支持innerHTML的dom对象,先将html串写到临时dom对象的innerHTML属性中,然后再用replaceChild方法将临时DOM对象的对应子节点替换到table节点里面。其它标签思路类似。

不管怎样解决,都是造成相对来说比较冗余的的代码,所以说IE有时候真就是奇葩,不过其寄生在牛逼的windows系统上,没人能耐他何。

html()函数的优点

看看innerHTML属性的缺点,就知道jQuery中html()函数的优点了,它是兼容所有浏览的,不存在html5标签不支持的问题,不存在href,src属性被转换的问题,不存在某些标签设置不了html串的问题,总之就是一句话,用它基本就万事无忧了,至少功能的实现上是这样。

html()函数的缺点

看来jQuery的html()函数似乎完美无限了,其实不然,它的完美只表现它的功能上,它兼容了所有浏览器,包括IE。但偏偏也是IE,尽管兼容了,性能并不乐观,如果使用html()函数设置大数据量的html串的话,那将是场灾难。

在IE下,html()函数的性能到底低到什么程度?电脑的配置为"i5 四核,8G内存,IE9",测试了用html()函数设置2000行4列的table,其平均耗时达到27秒!具体什么原因导致html()在IE下这么慢,个人粗略看过源码,觉得使用try方式是主要原因之一,有兴趣的同学可以深入研究一下。

目前有 1 条留言 其中:访客:1 条, 博主:0 条

  1. sunsong : 2014年05月08日18:04:00  -49楼 @回复 回复

    给楼主顶一个

给我留言

留言无头像?


×