为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

Javascript CloneNode 在IE上面的一个有关问题

2018-04-16 6页 doc 20KB 6阅读

用户头像

is_531654

暂无简介

举报
Javascript CloneNode 在IE上面的一个有关问题Javascript CloneNode 在IE上面的一个有关问题 Javascript CloneNode 在IE下面的一个问题 相信大家都用过cloneNode这个方法,这个方法很不错,效率也很高,推荐使用。最近在使 用它的时候,发现了一个隐藏的比较深的问题,和大家享一下。这个问题不像clone select 来得有名气,先看代码: style type='text/css' input.focus{border:1px solid red background-color:yellow} /style inp...
Javascript CloneNode 在IE上面的一个有关问题
Javascript CloneNode 在IE上面的一个有关问 Javascript CloneNode 在IE下面的一个问题 相信大家都用过cloneNode这个方法,这个方法很不错,效率也很高,推荐使用。最近在使 用它的时候,发现了一个隐藏的比较深的问题,和大家享一下。这个问题不像clone select 来得有名气,先看代码: style type='text/css' input.focus{border:1px solid red background-color:yellow} /style input type= text name= testinput check= num id= myinput / script type= text/javascript var originalInput = $('myinput') $E.on(input,'focus',function{$D.addClass(this,'focus')}) $E.on(input,'blur',function{$D.removeClass(this,'focus')}) var clonedInput = originalInput.cloneNode(true)//deep copy clonedInput.removeAttribute('id')//remove id document.body.appendChild(clonedInput) /script 注:$,$D,$E等是在YUI库上面封装的一些方法,这里只为写及说明方便。 好了,运行程序,奇怪的问题出现了,clonedInput 的 focus事件竟然触发了 originalInput 的 focus 事件~~~(注:只在IE有此现象,FF下正常,others没测)。有些人可能会认为这 是YUI库的bug,这点我可以很负责任的告诉你这不是YUI库的bug,而是IE自己的bug ? bug : feature。 没辙了吧,看下MSDN的说明: cloneNode Method Copies a reference to the object from the document hierarchy. Syntax oClone = object.cloneNode([bCloneChildren]) Parameters bCloneChildren Optional. Boolean that specifies one of the following values: FALSE Cloned objects do not include childNodes. TRUE Cloned objects include childNodes. Return Value Returns a reference to the newly created node. Remarks The cloneNode method copies an object, attributes, and, if specified, the childNodes. When you refer to the ID of a cloned element, a collection is returned. cloneNodedoes not work on an IFRAME directly. You must call cloneNodethrough the all collection. 看完后估计都很失望,没任何迹象。。。 再来看下另外一种写法: script type= text/javascript var originalInput = $('myinput') originalInput.onfocus = function{$D.addClass(this,'focus')} originalInput.onblur = function{$D.removeClass(this,'focus')} var clonedInput = originalInput.cloneNode(true)//deep copy clonedInput.removeAttribute('id')//remove id document.body.appendChild(clonedInput) /script 这种写法不会有问题,事件触发得都很正常。 根据MSDN的解释,深度复制会复制所有子结点,这里直接写originalInput.onfocus = …, 这时的onfucs已经算是originalInput的一个属性了(注:FF并非如此),所以可以正常复 制。至于这2种事件绑定的差异,这里就不作解释了,自己搜索吧。 看下例1的问题,问题出在$E.on(input,’focus’,function {$D.addClass(this,’focus’)}) 的this上面。以下是我的理解:看下YUI的源码可知这 是通过IE特有的attachEvent方法添加事件的,绑定的方法不会作为input的一个属性来对 待,这个方法只是和focus这个事件绑定了,我把它理解为一个引用指向了这个方法而已, 在内存保存着。在复制的时候,这个方法不会被复制,但 focus这个事件被复制了,即复制 出来的input的focus事件指向了这个方法,这个方法在内存中只存在一份。但这个方法一 开始就被创建了,方法里面的this的context是input,它们已经融为一体了,无法改变。 在clonedInput触发focus事件了,的确是触发了绑定的事件,但因为方法里面的this是 input,而不是clonedInput,所以出现这个怪异的现象。 (注:以上观点只是本人的猜测,也不知是否完全正确,请读者自行判断。请见后面的 mootools的说法) 好了,既然知道是因为this指向不对引起的,解决方法也很简单,如下: script type= text/javascript var originalInput = $('myinput') $E.on(input,'focus',function(e){ $D.addClass($E.getTarget(e),'focus')//use $E.getTarget(e) method to get the correct event obj. }) $E.on(input,'blur',function(e){$D.removeClass($E.getTarget(e),'focus')}) var clonedInput = originalInput.cloneNode(true)//deep copy clonedInput.removeAttribute('id')//remove id document.body.appendChild(clonedInput) /script 好了,万事OK了。 最后,请大家参考以下mootools的Daniel Steigerwald(mootools有自己的clone方法)的 说法: jQuery explanation on IE issue: IE copies events bound via attachEvent when using cloneNode. Calling detachEvent on the clone will also remove the events from the orignal. In order to get around this, we use innerHTML. Unfortunately, this means some modifications to attributes in IE that are actually only stored as properties will not be copied (such as the the name attribute on an input). clone: function(contents, keepid) { var clone = this.cloneNode(!!contents) function cleanAndFix(cloned, orig) { cloned.uid = null if (!keepid) cloned.removeAttribute('id') if (Browser.Engine.trident) { var shallowClone = orig.cloneNode(false) cloned.clearAttributes//关键是这2步 cloned.mergeAttributes(shallowClone)//关键是这2步 } return cloned } if (contents) { var cEls = clone.getElementsByTagName('*'), tEls = Browser.Engine.trident this.getElementsByTagName('*') for (var i = cEls.length i-- ) cleanAndFix(cEls[i], tEls tEls[i]) } return $(cleanAndFix(clone, this)) } 以前用过mootools的这个方法,一直没发现原来里面有这么多的玄机,可见写代码库是一件 多么不容易的事情啊,对他们表示由衷的敬佩~
/
本文档为【Javascript CloneNode 在IE上面的一个有关问题】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索