WEB开发网
开发学院网页设计JavaScript Prototype1.5 诡异错误一例 阅读

Prototype1.5 诡异错误一例

 2010-09-14 13:21:59 来源:WEB开发网   
核心提示:示范代码:<divid="test-parent"><divclass="test-child">child</div></div><script>//获取childdivvarc=document.getElement

示范代码:<divid="test-parent"> 
 <divclass="test-child">child</div> 
</div><script> 
//获取childdiv 
varc=document.getElementsByClassName(’test-child’)[0]; 
//克隆一份childdiv 
newInsertion.After(c,$(’test-parent’).innerHTML); 
//获取克隆后插入的第二个div 
varc2=$$(’.test-child’)[1]; 
c2.hide();//Error:Objectdoesn’tsupportthispropertyormethod 
</script> 

从Prototype1.5开始,$()、$$()和getElementsByClassName()这三个方法取得的结果对象,在返回前Prototype都会用Element.extend(elm)函数进行封装。这样结果对象就自动拥有了Element对象的很多实例方法,原来比如 

Element.hide(element); 

这样的调用可以简化为 

$(element).hide(); 

那么开头部分代码报错的原因何解呢?打印出"$(’test-parent’).innerHTML"的输出可看出些端倪来,IE7的输出结果如下: 

<DIVclass=test-child_extended="true">child</DIV> 

奥妙就在这个_extended属性上,看Element.extend()的源码 

Element.extend=function(element){ 
 if(!element)return; 
 if(_nativeExtensions)returnelement; if(!element._extended&&element.tagName&&element!=window){ 
  varmethods=Element.Methods,cache=Element.extend.cache; 
  for(propertyinmethods){ 
   varvalue=methods[property]; 
   if(typeofvalue==’function’) 
    element[property]=cache.findOrStore(value); 
  } 
 } element._extended=true; 
 returnelement; 
} 
原来Element.extend(elm)方法会给element增加一个_extended属性,当element再次被$()等函数取得并返回时如果发现已经有了这个属性则停止执行。 

所以,开头代码报错的原因就在于通过innerHTML复制一个element的时候,_extended也被复制了进去,这样被复制后插入的新element就无法继承到Element的实例方法。对新element调用这些实例方法时就抛出错误来。 

解决办法 

从innerHTML中过滤掉_extended属性 

手工清除新对象的_extended属性后重新调用$() 

用DOM方法替换innerHTML 

Tags:Prototype 诡异 错误

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接