我是FE,也是Fe

前端来源于不断的点滴积累。我一直在努力。

统计

留言簿(15)

阅读排行榜

评论排行榜

使用IE 8+ DOM prototype定义扩展DOM原生方法

大家知道在Firefox上DOM是没有IE的innerText方法的(取而代之的是textContent属性)。好在Firefox可以利用定义一个DOM方法。下面是常见的源代码。
HTMLElement.prototype.__defineGetter__("innerText"function () {
            
return this.innerHTML.replace(/\<[^\>]+\>/gi,"");
});

HTMLElement.prototype.__defineSetter__(
"innerText"function(s) {
            
this.innerHTML=s;     
});

HTMLElemnent 是非IE浏览器上一个Class,通过Firefox在prototype提供的__defineGetter__方法可以定义一个HTMLElement的innerText的get方法。这样在非IE浏览器上就可以使用innerText属性。

但是这不是今天的重点,今天的想法是反过来,能否使用IE的prototype来扩展来实现在IE上有textContent方法。

大家知道所有的Class都继承自Object。在早期的Prototype javascript framework中,由于要兼容低版本的IE浏览器,需要在Object.prototype上直接扩展出方法,这样确实能实现DOM原生方法的扩充,但是从prototype chain上来看,Element继承自Object,在查找扩充方法时需要的时间自然要长。而且这样的会导致所有的对象上都会有DOM的扩展方法。最近在看一本书Pro Internet Explorer 8 & 9 Development: Developing Powerful Applications for The Next Generation of IE 上面介绍了在IE 8,9上提供的原生的DOM扩展方式。

下面使用IE的DOM扩展实现IE 的textContent属性。
// 定义textContent方法到IE的innerText
Object.defineProperty(Element.prototype, "textContent",

    get: 
function () { return this.innerText; } ,
    set: 
function (content) {this.innerText= content; } 
}); 
Object.defineProperty是IE8+提供的方法,功能与非IE浏览器的__defineGetter__/__defineSetter__相似。通过上面的扩展,就可以在IE8+上使用类似document.getElementById("").textContent属性。
要注意的是,如果页面上加了一段类似兼容低版本的IE代码时,不能使用defineObject方法。
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
上面的这个meta告诉IE8模拟IE7运行,之前我以为模拟只是用IE7的展现方式,没想到javascript的执行方式也如IE7

如果要删除自定义的DOM扩充方法也很简单。
delete Element.prototype.textContent;
这样再尝试读取textContext属性就是undefined了。
你可能会想,可以不可以使用delete删除IE原生方法了?当然是不行的。
    delete Element.prototype.innerText;//do nothing
    alert(document.getElementById("div1").innerText);//still works
如果尝试删除IE的原生方法是没有效果的,不过也不会报错。

结论:IE 8+浏览器正在吸收其他浏览器的优点,我们看到IE浏览器的性能再逐步提升,开发特性也在增强,随着MS 在IE的投入加大,IE浏览器与其他浏览器的差距会慢慢缩小。

posted on 2010-12-06 00:08 衡锋 阅读(3228) 评论(0)  编辑  收藏 所属分类: Web开发


只有注册用户登录后才能发表评论。


网站导航: