ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:51.04KB ,
资源ID:22806754      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/22806754.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(javascript 动态插入技术.docx)为本站会员(b****1)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

javascript 动态插入技术.docx

1、javascript 动态插入技术最近发现各大类库都能利用div.innerHTML=HTML片断来生成节点元素,再把它们插入到目标元素的各个位置上。这东西实际上就是insertAdjacentHTML,但是IE可恶的innerHTML把这优势变成劣势。首先innerHTML会把里面的某些位置的空白去掉,见下面运行框的结果:(复制运行) IE的innerHTML By 司徒正美 window.onload = function() var div = document.createElement(div); div.innerHTML = 司徒正美 alert(| + div.innerHTM

2、L + |); var c = div.childNodes; alert(生成的节点个数 + c.length); for(var i=0,n=c.length;in;i+) alert(ci.nodeType); if(ci.nodeType = 1) alert(: +ci.childNodes.length); 另一个可恶的地方是,在IE中以下元素的innerHTML是只读的:col、 colgroup、frameset、html、 head、style、table、tbody、 tfoot、 thead、title 与 tr。为了收拾它们,Ext特意弄了个insertIntoTabl

3、e。insertIntoTable就是利用DOM的insertBefore与appendChild来添加,情况基本同jQuery。不过jQuery是完全依赖这两个方法,Ext还使用了insertAdjacentHTML。为了提高效率,所有类库都不约而同地使用了文档碎片。基本流程都是通过div.innerHTML提取出节点,然后转移到文档碎片上,然后用insertBefore与appendChild插入节点。对于火狐,Ext还使用了createContextualFragment解析文本,直接插入其目标位置上。显然,Ext的比jQuery是快许多的。不过jQuery的插入的不单是HTML片断,还

4、有各种节点与jQuery对象。下面重温一下jQuery的工作流程吧。append: function() /传入arguments对象,true为要对表格进行特殊处理,回调函数 return this.domManip(arguments, true, function(elem) if (this.nodeType = 1) this.appendChild( elem ); );,domManip: function( args, table, callback ) if ( this0 ) /如果存在元素节点 var fragment = (this0.ownerDocument | t

5、his0).createDocumentFragment(), /注意这里是传入三个参数 scripts = jQuery.clean( args, (this0.ownerDocument | this0), fragment ), first = fragment.firstChild; if ( first ) for ( var i = 0, l = this.length; i 1 | i 0 ? fragment.cloneNode(true) : fragment ); if ( scripts ) jQuery.each( scripts, evalScript ); retu

6、rn this; function root( elem, cur ) return table & jQuery.nodeName(elem, table) & jQuery.nodeName(cur, tr) ? (elem.getElementsByTagName(tbody)0 | elem.appendChild(elem.ownerDocument.createElement(tbody) : elem; /elems为arguments对象,context为document对象,fragment为空的文档碎片clean: function( elems, context, fra

7、gment ) context = context | document; / !context.createElement fails in IE with an error but returns typeof object if ( typeof context.createElement = undefined ) /确保context为文档对象 context = context.ownerDocument | context0 & context0.ownerDocument | document; / If a single string is passed in and its

8、 a single tag / just do a createElement and skip the rest /如果文档对象里面只有一个标签,如 /我们大概可能是在外面这样调用它$(this).append() /这时就直接把它里面的元素名取出来,用document.createElement(div)创建后放进数组返回 if ( !fragment & elems.length = 1 & typeof elems0 = string ) var match = /$/.exec(elems0); if ( match ) return context.createElement( m

9、atch1 ) ; /利用一个div的innerHTML创建众节点 var ret = , scripts = , div = context.createElement(div); /如果我们是在外面这样添加$(this).append(表格1,表格1,表格1) /jQuery.each按它的第四种支分方式(没有参数,有length)遍历aguments对象,callback.call( value, i, value ) jQuery.each(elems, function(i, elem)/i为索引,elem为arguments对象里的元素 if ( typeof elem = num

10、ber ) elem += ; if ( !elem ) return; / Convert html string into DOM nodes if ( typeof elem = string ) / Fix XHTML-style tags in all browsers elem = elem.replace(/(*?)/g, function(all, front, tag) return tag.match(/(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? all : front + ; ); / Trim

11、whitespace, otherwise indexOf wont work as expected var tags = elem.replace(/s+/, ).substring(0, 10).toLowerCase(); var wrap = / option or optgroup !tags.indexOf(opt) & 1, , | !tags.indexOf(leg) & 1, , | tags.match(/(thead|tbody|tfoot|colg|cap)/) & 1, , | !tags.indexOf(tr) & 2, , | / matched above (

12、!tags.indexOf(td) | !tags.indexOf(th) & 3, , | !tags.indexOf(col) & 2, , | / IE cant serialize and tags normally !jQuery.support.htmlSerialize &/用于创建link元素 1, div, | 0, , ; / Go to html and back, then peel off extra wrappers div.innerHTML = wrap1 + elem + wrap2;/比如 +表格1+ / Move to the right depth wh

13、ile ( wrap0- ) div = div.lastChild; /处理IE自动插入tbody,如我们使用$()创建HTML片断,它应该返回 /,而IE会返回 if ( !jQuery.support.tbody ) / String was a , *may* have spurious var hasBody = /tbody/i.test(elem), tbody = !tags.indexOf(table) & !hasBody ? div.firstChild & div.firstChild.childNodes : / String was a bare or wrap1

14、= & !hasBody ? div.childNodes : ; for ( var j = tbody.length - 1; j = 0 ; -j ) /如果是自动插入的里面肯定没有内容 if ( jQuery.nodeName( tbody j , tbody ) & !tbody j .childNodes.length ) tbody j .parentNode.removeChild( tbody j ); / IE completely kills leading whitespace when innerHTML is used if ( !jQuery.support.le

15、adingWhitespace & /s/.test( elem ) ) div.insertBefore( context.createTextNode( elem.match(/s*/)0 ), div.firstChild ); /把所有节点做成纯数组 elem = jQuery.makeArray( div.childNodes ); if ( elem.nodeType ) ret.push( elem ); else /全并两个数组,merge方法会处理IE下object元素下消失了的param元素 ret = jQuery.merge( ret, elem ); ); if (

16、fragment ) for ( var i = 0; reti; i+ ) /如果第一层的childNodes就有script元素节点,就用scripts把它们收集起来,供后面用globalEval动态执行 if ( jQuery.nodeName( reti, script ) & (!reti.type | reti.type.toLowerCase() = text/javascript) ) scripts.push( reti.parentNode ? reti.parentNode.removeChild( reti ) : reti ); else /遍历各层节点,收集scri

17、pt元素节点 if ( reti.nodeType = 1 ) ret.splice.apply( ret, i + 1, 0.concat(jQuery.makeArray(reti.getElementsByTagName(script) ); fragment.appendChild( reti ); return scripts;/由于动态插入是传入三个参数,因此这里就返回了 return ret;,真是复杂的让人掉眼泪!不过jQuery的实现并不太高明,它把插入的东西统统用clean转换为节点集合,再把它们放到一个文档碎片中,然后用appendChild与insertBefore插入

18、它们。在除了火狐外,其他浏览器都支持insertAdjactentXXX家族的今日,应该好好利用这些原生API。下面是Ext利用insertAdjactentHTML等方法实现的DomHelper方法,官网给出的数据:Insertion MethodIE7 beta 2IE6FF 1.5Opera 9DOM.7301.35.420.280HTML Fragments.360.380.400.260Template.320.335.385.220Compiled Template.295.300.350.210数据来源:Tutorial:使用DomHelper 创建元素的DOM、HTML片断和模

19、版这数据有点老了,而且最新3.03早就解决了在IE table插入内容的诟病(table,tbody,tr等的innerHTML都是只读,insertAdjactentHTML,pasteHTML等方法都无法修改其内容,要用又慢又标准的DOM方法才行,Ext的早期版本就在这里遭遇滑铁卢了)。可以看出,结合insertAdjactentHTML与文档碎片后,IE6插入节点的速度也得到难以置信的提升,直逼火狐。基于它,Ext开发了四个分支方法insertBefore、insertAfter、insertFirst、append,分别对应jQuery的before、after、prepend与app

20、end。不过,jQuery还把这几个方法巧妙地调换了调用者与传入参数,衍生出insertBefore、insertAfter、prependTo与appendTo这几个方法。但不管怎么说,jQuery这样一刀切的做法实现令人不敢苛同。下面是在火狐中实现insertAdjactentXXX家族的一个版本:(function() if (HTMLElement in this) if(insertAdjacentHTML in HTMLElement.prototype) return else return function insert(w, n) switch(w.toUpperCase()

21、 case BEFOREEND : this.appendChild(n) break case BEFOREBEGIN : this.parentNode.insertBefore(n, this) break case AFTERBEGIN : this.insertBefore(n, this.childNodes0) break case AFTEREND : this.parentNode.insertBefore(n, this.nextSibling) break function insertAdjacentText(w, t) insert.call(this, w, doc

22、ument.createTextNode(t | ) function insertAdjacentHTML(w, h) var r = document.createRange() r.selectNode(this) insert.call(this, w, r.createContextualFragment(h) function insertAdjacentElement(w, n) insert.call(this, w, n) return n HTMLElement.prototype.insertAdjacentText = insertAdjacentText HTMLEl

23、ement.prototype.insertAdjacentHTML = insertAdjacentHTML HTMLElement.prototype.insertAdjacentElement = insertAdjacentElement)()我们可以利用它设计出更快更合理的动态插入方法。下面是我的一些实现:/四个插入方法,对应insertAdjactentHTML的四个插入位置,名字就套用jQuery的/stuff可以为字符串,各种节点或dom对象(一个类数组对象,便于链式操作!)/代码比jQuery的实现简洁漂亮吧! append:function(stuff) return do

24、m.batch(this,function(el) dom.insert(el,stuff,beforeEnd); ); , prepend:function(stuff) return dom.batch(this,function(el) dom.insert(el,stuff,afterBegin); ); , before:function(stuff) return dom.batch(this,function(el) dom.insert(el,stuff,beforeBegin); ); , after:function(stuff) return dom.batch(this

25、,function(el) dom.insert(el,stuff,afterEnd); ); 它们里面都是调用了两个静态方法,batch与insert。由于dom对象是类数组对象,我仿效jQuery那样为它实现了几个重要迭代器,forEach、map与filter等。一个dom对象包含复数个DOM元素,我们就可以用forEach遍历它们,执行其中的回调方法。batch:function(els,callback) els.forEach(callback); return els;/链式操作,insert方法执行jQuery的domManip方法相应的机能(dojo则为place方法),但i

26、nsert方法每次处理一个元素节点,不像jQuery那样处理一组元素节点。群集处理已经由上面batch方法分离出去了。insert : function(el,stuff,where) /定义两个全局的东西,提供内部方法调用 var doc = el.ownerDocument | dom.doc, fragment = doc.createDocumentFragment(); if(stuff.version)/如果是dom对象,则把它里面的元素节点移到文档碎片中 stuff.forEach(function(el) fragment.appendChild(el); ) stuff = fragment; /供火狐与IE部分元素调用 dom._insertAdjacentElement = function(el,node,where) switch (where) case beforeBegin: el.parentNode.insertBefore(node,el) break; case afterBegin: el.insertBefore(node,el.firstChild); break; case beforeEnd: el.appendChild(node); break; case afterEnd: if (el.next

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1