今天有人在群里贴出这样一段代码:

 <body>
<input type="text" id="username" value="文本输出鸟" />
<script>
var node = document.getElementById("username");
node.prototype.right = function (){
alert(this.nodeType);
}
document.body.right()

</script>
</body> 
本段运行时,document.body.right()这段会报错,提示:body.right方法没有定义,看到这个问题我首先想到的是代码中取到的node是一个input元素,是HTMLElement的一个实例,所以用prototype给node定义方法,body无法调用。就尝试加了个constructor,改为node.constructor.prototype.right = function (){
alert(this.nodeType);
}
运行还是不行,但是input元素却可以调用right()方法,<input type="text" id="username1" value="文本输出鸟" />
既document.getElementById("username1").right();是可以实现的。用浏览器调试工具查看才发现,node.constructor取到的是HTMLInputElement,所以才会产生这样的效果。

图1:浏览器查看效果

那么干脆再加一个constructor看看什么 效果

图2:浏览器查看效果

嗯,这次看着正常了。

最终代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
</head>
<body>
<input type="text" id="username" value="文本输出鸟" />
<input type="text" id="username1" value="文本输出鸟" />
<script>
var node = document.getElementById("username");
node.constructor.constructor.prototype.right = function (){
alert(this.nodeType);
}
document.getElementById("username1").right();
document.body.right();

</script>
</body>

</html>

但是在ie8试又出问题了,ie不支持constructor、prototype,那么究竟是为什么呢?

查找下才发现,原来Dom标准下,每个html元素都是继承自HTMLElement。而HTMLElement继承自Element,Element继承自node。

这就是html元素的继承关系。

知道了HTMLElement这个类,就可以很方便的用Prototype来扩展每个HTML元素的方法或者属性。

  但是在IE中将这个类隐藏了,不能通过代码访问。为了达到同样的目的,需要通过如下代码来进行修复:

varDOMElement={
  extend:function(name,fn){//添加名称为name的方法fn
  
    if(!document.all)//除了ie而外的浏览器都能够访问到HTMLElement这个类
      eval("HTMLElement.prototype."+name+"=fn");
    else{
      //  IE中不能访问HTMLElement这个类
      //  为了达到同样的目的,必须重写下面几个函数
      //  document.createElement
      //  document.getElementById
      //  document.getElementsByTagName
      //  这几个函数都是获得HTML元素的方法
      //  修改这些方法,使得通过这些方法获得的每个元素拥有名称为name的方法fn
      var_createElement=document.createElement;
      document.createElement=function(tag){
        var_elem=_createElement(tag);
        eval("_elem."+name+"=fn");//_elem[name]=fn;也可以达到同样的目的
        return_elem;
      }
      var_getElementById=document.getElementById;
      document.getElementById=function(id){
        var_elem=_getElementById(id);
        eval("_elem."+name+"=fn");
        return_elem;
      }
      var_getElementsByTagName=document.getElementsByTagName;
      document.getElementsByTagName=function(tag){
        var_arr=_getElementsByTagName(tag);
        for(var_elem=0;_elem<_arr.length;_elem++)
          eval("_arr[_elem]."+name+"=fn");
        return_arr;
      }
    }
  }
};

使用:DOMElement.extend("contents",function(){returnthis.innerHTML});

posted on 2012-06-26 14:31  lianQ  阅读(274)  评论(0)    收藏  举报