append: function() { //传入arguments对象,true为要对表格进行特殊处理,回调函数 return this.domManip(arguments, true, function(elem){ if (this.nodeType == 1) this.appendChild( elem ); }); }, domManip: function( args, table, callback ) { if ( this[0] ) {//如果存在元素节点 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), //注意这里是传入三个参数 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), first = fragment.firstChild;
if ( first ) for ( var i = 0, l = this.length; i callback.call( root(this[i], first), this.length > 1 || i > 0 ? fragment.cloneNode(true) : fragment );
if ( scripts ) jQuery.each( scripts, evalScript ); }
// !context.createElement fails in IE with an error but returns typeof 'object' if ( typeof context.createElement === "undefined" ) //确保context为文档对象 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
// If a single string is passed in and it's a single tag // just do a createElement and skip the rest //如果文档对象里面只有一个标签,如
//我们大概可能是在外面这样调用它$(this).append("
") //这时就直接把它里面的元素名取出来,用document.createElement("div")创建后放进数组返回 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { var match = /^$/.exec(elems[0]); if ( match ) return [ context.createElement( match[1] ) ]; } //利用一个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 === "number" ) 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 + ">" + tag + ">"; });
// Trim whitespace, otherwise indexOf won't work as expected var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
var wrap = // option or optgroup !tags.indexOf(" [ 1, "" ] ||
!tags.indexOf(" [ 1, "" ] ||
tags.match(/^ [ 1, "
", "
" ] ||
!tags.indexOf("
[ 2, "
", "
" ] ||
// matched above (!tags.indexOf("
[ 3, "
", "
" ] ||
!tags.indexOf("
[ 2, "
", "
" ] ||
// IE can't serialize and <script> tags normally <BR> !jQuery.support.htmlSerialize &&//用于创建link元素 <BR> [ 1, "div<div>", "" ] || <br><br> [ 0, "", "" ]; <br><br> // Go to html and back, then peel off extra wrappers <BR> div.innerHTML = wrap[1] + elem + wrap[2];//比如"<table><tbody><tr>" +<td>表格1</script>
+""
// Move to the right depth while ( wrap[0]-- ) div = div.lastChild;
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.nextSibling) el.parentNode.insertBefore(node,el.nextSibling); else el.parentNode.appendChild(node); break; } }; //供火狐调用 dom._insertAdjacentHTML = function(el,htmlStr,where){ var range = doc.createRange(); switch (where) { case "beforeBegin"://before range.setStartBefore(el); break; case "afterBegin"://after range.selectNodeContents(el); range.collapse(true); break; case "beforeEnd"://append range.selectNodeContents(el); range.collapse(false); break; case "afterEnd"://prepend range.setStartAfter(el); break; } var parsedHTML = range.createContextualFragment(htmlStr); dom._insertAdjacentElement(el,parsedHTML,where); }; //以下元素的innerHTML在IE中是只读的,调用insertAdjacentElement进行插入就会出错 // col, colgroup, frameset, html, head, style, title,table, tbody, tfoot, thead, 与tr; dom._insertAdjacentIEFix = function(el,htmlStr,where){ var parsedHTML = dom.parseHTML(htmlStr,fragment); dom._insertAdjacentElement(el,parsedHTML,where) }; //如果是节点则复制一份 stuff = stuff.nodeType ? stuff.cloneNode(true) : stuff; if (el.insertAdjacentHTML) {//ie,chrome,opera,safari都已实现insertAdjactentXXX家族 try{//适合用于opera,safari,chrome与IE el['insertAdjacent'+ (stuff.nodeType ? 'Element':'HTML')](where,stuff); }catch(e){ //IE的某些元素调用insertAdjacentXXX可能出错,因此使用此补丁 dom._insertAdjacentIEFix(el,stuff,where); } }else{ //火狐专用 dom['_insertAdjacent'+ (stuff.nodeType ? 'Element':'HTML')](el,stuff,where); } }
insert方法在实现火狐插入操作中,使用了W3C DOM Range对象的一些罕见方法,具体可到火狐官网查看。下面实现把字符串转换为节点,利用innerHTML这个伟大的方法。Prototype.js称之为_getContentFromAnonymousElement,但有许多问题,dojo称之为_toDom,mootools的Element.Properties.html,jQuery的clean。Ext没有这东西,它只支持传入HTML片断的insertAdjacentHTML方法,不支持传入元素节点的insertAdjacentElement。但有时,我们需要插入文本节点(并不包裹于元素节点之中),这时我们就需要用文档碎片做容器了,insert方法出场了。
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn