解密jQuery内核 DOM操作

简介:

jQuery针对DOM操作的插入的方法有大概10种

append、prepend、before、after、replaceWith

appendTo、prependTo、insertBefore、insertAfter、replaceAll

分2组,上下对照,实现同样的功能。主要的不同是语法——特别是内容和目标的位置

依赖的domManipbuildFragment模块在之前就分析过了

 


在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点

对于 .after(), 选择表达式在函数的前面,参数是将要插入的内容。

对于.insertAfter(), 刚好相反,内容在方法前面,它将被放在参数里元素的后面。

after

复制代码
after: function() {
    return this.domManip( arguments, function( elem ) {
        if ( this.parentNode ) {
            this.parentNode.insertBefore( elem, this.nextSibling );
        }
    });
},
复制代码

之前提过了所有的方法靠this.domManip合并参数处理,内部通过buildFragment模块构建文档碎片

然后把每一个方法的具体执行通过回调的方式提供出来处理

DOM操作并未提供一个直接可以在当前节点后插入一个兄弟节点的方法,但是提供了一个类似的方法

insertBefore() 方法:可在已有的子节点前插入一个新的子节点。语法 :insertBefore(newchild,refchild)

看看jQuery如何处理的

例如

inner.after('<p>Test</p>');

内部就会把  '<p>Test</p>' 通过buildFragment构建出文档elem

然后通过  this.parentNode.insertBefore( elem, this.nextSibling );

这里的this 就是对应着inner ,elem就是‘<p>Test</p>’

看到这里就很好理解了after的实现了

用原生方法简单模拟

复制代码
var  inner = document.getElementsByClassName('inner')
for(var i =0 ; i<inner.length;i++){
    var elem = inner[i]
    var div = document.createElement('div')
    div.innerHTML = 'aaaa'
    elem.parentNode.insertBefore(div,elem.nextSibling)
}
复制代码

 


insertAfter

jQuery代码的设计者很聪明的,都尽可能的合并相似功能的方法,代码更加精炼美观

复制代码
jQuery.each({
    appendTo: "append",
    prependTo: "prepend",
    insertBefore: "before",
    insertAfter: "after",
    replaceAll: "replaceWith"
}, function( name, original ) {
    jQuery.fn[ name ] = function( selector ) {
                           
    };
});
复制代码

DEMO

$('<p>Test</p>').insertAfter('.inner');

通过$('<p>Test</p>')构建一个文档,对象通过insertAfter方法插入到所有class等于inner的节点后

表达的意思与after是一样的,主要的不同是语法——特别是内容和目标的位置

复制代码
jQuery.fn[ name ] = function( selector ) {
        var elems,
            ret = [],
            insert = jQuery( selector ),
            last = insert.length - 1,
            i = 0;

        for ( ; i <= last; i++ ) {
            elems = i === last ? this : this.clone( true );
            jQuery( insert[ i ] )[ original ]( elems );

            // Support: QtWebKit
            // .get() because core_push.apply(_, arraylike) throws
            core_push.apply( ret, elems.get() );
        }

        return this.pushStack( ret );
    };
复制代码

看具体的实现方法中.insertAfter('.inner');inner其实就被当作selector传入进来了

selector可能只是字符串选择器内部就需要转化,insert = jQuery( selector ),

 

$('<p>Test</p>')就是构建出来的文档碎片节点,那么如果赋给insert有多个的时候就需要完全克隆一份副本了,所以就直接赋给

elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems );

 

依旧是执行after

jQuery( insert[ i ] )[ original ]( elems );

 

最终还需要返回这个构建的新节点

收集构建的节点

core_push.apply( ret, elems.get() );

构建一个新jQuery对象,以便实现链式

this.pushStack( ret );

 

可见after 与 insertAfter 本质本质其实都是一样的,只是通过不同的方式调用

 


before()

根据参数设定,在匹配元素的前面插入内容

复制代码
before: function() {
        return this.domManip( arguments, function( elem ) {
            if ( this.parentNode ) {
                this.parentNode.insertBefore( elem, this );
            }
        });
    },
复制代码

类似after只是替换了第二个参数,改变插入的位置

 


append()

在每个匹配元素里面的末尾处插入参数内容

复制代码
append: function() {
    return this.domManip( arguments, function( elem ) {
        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
            var target = manipulationTarget( this, elem );
            target.appendChild( elem );
        }
    });
},
复制代码

内部增加节点,直接可以调用appendChild方法

 


prepend()

将参数内容插入到每个匹配元素的前面(元素内部)

复制代码
prepend: function() {
    return this.domManip( arguments, function( elem ) {
        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
            var target = manipulationTarget( this, elem );
            target.insertBefore( elem, target.firstChild );
        }
    });
},
复制代码

类似after只是替换了第二个参数,改变插入的位置

 


replaceWith()

用提供的内容替换集合中所有匹配的元素并且返回被删除元素的集合。

.replaceWith()可以从DOM中移除内容,然后在这个地方插入新的内容。请看下面的例子:

<div class="container">
  <div class="inner first">Hello</div>
  <div class="inner second">And</div>
  <div class="inner third">Goodbye</div>
</div>

我们可以用指定的HTML替换第二个 inner <div> :

$('div.second').replaceWith('<h2>New heading</h2>');

结果如下:

<div class="container">
  <div class="inner first">Hello</div>
  <h2>New heading</h2>
  <div class="inner third">Goodbye</div>
</div>

或者我们可以选择一个元素把它当做替换的内容:

$('div.third').replaceWith($('.first'));

结果如下:

 

<div class="container">
  <div class="inner second">And</div>
  <div class="inner first">Hello</div>
</div>

从这个例子可以看出,用来替换的元素从老地方移到新位置,而不是复制。

.replaceWith()方法,和大部分其他jQuery方法一样,返回jQuery对象,所以可以和其他方法链接使用,但是需要注意的是:对于该方法而言,该对象指向已经从 DOM 中被移除的对象,而不是指向替换用的对象。

 

复制代码
replaceWith: function() {
    var
        // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
        args = jQuery.map( this, function( elem ) {
            return [ elem.nextSibling, elem.parentNode ];
        }),
        i = 0;

    // Make the changes, replacing each context element with the new content
    this.domManip( arguments, function( elem ) {
        var next = args[ i++ ],
            parent = args[ i++ ];

        if ( parent ) {
            // Don't use the snapshot next if it has moved (#13810)
            if ( next && next.parentNode !== parent ) {
                next = this.nextSibling;
            }
            jQuery( this ).remove();
            parent.insertBefore( elem, next );
        }
    // Allow new content to include elements from the context set
    }, true );

    // Force removal if there was no new content (e.g., from empty arguments)
    return i ? this : this.remove();
},
复制代码

删除目标节点

jQuery( this ).remove();

然后再插入一个新节点

parent.insertBefore( elem, next );


本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3516081.html,如需转载请自行联系原作者

相关文章
|
11月前
|
JavaScript 前端开发 开发者
深入了解jQuery:轻松实现高效的DOM操作
【10月更文挑战第11天】深入了解jQuery:轻松实现高效的DOM操作
176 0
|
12月前
|
JavaScript 前端开发
jQuery 操作 DOM 及 CSS
本文介绍了如何使用jQuery进行DOM操作和CSS样式的修改,包括如何获取和设置元素的文本内容、属性值、添加和删除元素,以及如何使用jQuery的addClass、removeClass、toggleClass、hasClass和css方法来操作元素的CSS。通过示例代码,展示了jQuery在实际开发中的便捷性。
jQuery 操作 DOM 及 CSS
|
12月前
|
JSON JavaScript 前端开发
Jquery常用操作汇总,dom操作,ajax请求
本文汇总了jQuery的一些常用操作,包括DOM元素的选择、添加、移除,表单操作,以及如何使用jQuery发送Ajax请求,涵盖了GET、POST请求和文件上传等常见场景。
|
11月前
|
JavaScript 前端开发 API
深入理解jQuery:高效DOM操作与事件处理
【10月更文挑战第11天】深入理解jQuery:高效DOM操作与事件处理
116 0
|
JavaScript 前端开发
DOM操作有哪些方法可以改变元素的样式?
【6月更文挑战第30天】DOM操作有哪些方法可以改变元素的样式?
162 2
|
JavaScript 前端开发 开发者
DOM操作
【6月更文挑战第30天】DOM操作
148 1
|
JavaScript 前端开发 API
前端框架与库 - jQuery基础与DOM操作
【7月更文挑战第18天】jQuery 是一个简化JavaScript任务的库,以其“write less, do more”理念著称。核心功能包括DOM操作、事件处理和Ajax。DOM操作如选择元素(`$(&quot;p&quot;)`、`$(&quot;#myDiv&quot;)`、`$(&quot;.myClass&quot;)`)、创建及添加元素、修改属性和内容。事件处理如绑定(`click`)和触发(`trigger`)。常见问题涉及`$`符号冲突(使用`jQuery`代替)、异步加载管理和选择器性能优化。了解并规避这些问题能提升jQuery使用效率。
111 0
|
JavaScript 前端开发 API
jQuery对象与DOM对象简介及相互转换
jQuery对象与DOM对象简介及相互转换
140 0
|
11月前
|
JavaScript
DOM 节点列表长度(Node List Length)
DOM 节点列表长度(Node List Length)
|
11月前
|
JavaScript
HTML DOM 节点树
HTML DOM 节点是指在 HTML 文档对象模型中,文档中的所有内容都被视为节点。整个文档是一个文档节点,每个 HTML 元素是元素节点,元素内的文本是文本节点,属性是属性节点,注释是注释节点。DOM 将文档表示为节点树,节点之间有父子和同胞关系。