内容简介:前言:unwrap() 的解析请看
前言:
unwrap() 的解析请看 jQuery源码解析之replaceWith()/unwrap()
empty() 的解析请看 jQuery之text()的实现
一、 $() .empty()
作用:
清除被选元素的所有子节点和内容,包括事件和数据
注意:该方法不会移除被选元素本身或它的属性。
源码:
//源码6231行
empty: function() {
var elem,
i = 0;
for ( ; ( elem = this[ i ] ) != null; i++ ) {
//如果是元素节点的话
if ( elem.nodeType === 1 ) {
// Prevent memory leaks
//清空内容和事件,防止内存泄漏
jQuery.cleanData( getAll( elem, false ) );
// Remove any remaining nodes
//清空节点所有内容
elem.textContent = "";
}
}
return this;
},
简单实现:
$("#divTwo").empty()
//相当于
function customEmpty() {
let elem,
i = 0,array=[]
//DOM节点集合,querySelectorAll
//注意for循环的写法
for (; (elem = this[i]) != null; i++) {
//如果是元素节点的话,清空该节点的所有内容
if (elem.nodeType === 1) {
//jQuery.cleanData( getAll( elem, false ) );
elem.textContent = "";
}
}
//单个DOM节点,querySelector
if(this[i]===undefined){
if (this.nodeType === 1) {
//jQuery.cleanData( getAll( elem, false ) );
this.textContent = "";
}
}
return this;
}
customEmpty.call(divTwo)
二、 $() .remove()
作用:
移除被选元素 自身 ,包括所有的数据、事件和子节点。
源码:
//移除被选元素,包括所有的文本和子节点,不会保留移除元素的副本
//源码6159行
remove: function( selector ) {
return remove( this, selector );
},
解析:
可以看到, $() .remove() 方法实际上调用的是外部的大的 remove() 方法,并且只传了两个参数 this 、 selector
第三个参数是 keepData,即是否保留被移除元素的事件和数据,没有传参即默认false,在下面的 detach() 方法也是调用的 remove() 方法,并且第三个参数传了 true
detach: function( selector ) {
return remove( this, selector, true );
},
1、remove():
//源码6037行
//$().remove()调用:selector, undefined, undefined
function remove( elem, selector, keepData ) {
console.log(elem,selector,'elem6041')
var node,
//remove()不带参数的话,nodes=目标元素
//$("p").remove("#pTwo") elem=$("p") selector=#pTwo
nodes = selector ? jQuery.filter( selector, elem ) : elem,
i = 0;
console.log(nodes,'nodes6061')
for ( ; ( node = nodes[ i ] ) != null; i++ ) {
//如果keepData不为true,并且node为元素节点,则清除数据和事件
if ( !keepData && node.nodeType === 1 ) {
jQuery.cleanData( getAll( node ) );
}
//如果父节点存在,则removeChild
if ( node.parentNode ) {
if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
setGlobalEval( getAll( node, "script" ) );
}
node.parentNode.removeChild( node );
}
}
return elem;
}
解析:
① nodes 是经过处理后得到的要被移除的节点集合
② 循环 nodes,依次去除 nodes[i] 的事件和数据
③ 找到 nodes[i] 的父节点,并调用原生JS的 removeChild() 方法,去掉 nodes[i]
简单实现:
//无参数======
$("#divTwo").remove()
//相当于
// jQuery.cleanData(getAll(divTwo))
divTwo.parentNode.removeChild(divTwo)
当 $().remove() 有参数的话(比如: $("p").remove("#pTwo") ),就会调用jQuery.filter( selector, elem )方法
2、 $ .filter():
作用:
返回符合一定条件的元素,比如 $("p").remove("#pTwo") ,就是返回所有 <p> 标签中,id='pTwo' 的元素节点的集合,filter() 里面最后还调用了 jQuery.find.matchesSelector() 和 jQuery.find.matches() 方法,这两个方法内都会调用 Sizzle() 方法,而 Sizzle() 内调用了 select() 方法,select() 比较复杂,本文暂不贴码解析。
源码:
//返回符合一定条件的元素
//$("p").remove("#pTwo") expr=#pTwo elems=$("p")
//源码2925行
jQuery.filter = function( expr, elems, not ) {
//jQuery对象转换成DOM对象
var elem = elems[ 0 ];
if ( not ) {
expr = ":not(" + expr + ")";
}
//目标元素节点只有一个的情况
if ( elems.length === 1 && elem.nodeType === 1 ) {
return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
}
//elems 标签p的集合
//jQuery.grep,返回符合callback函数条件的数组,
// 这里就是过滤掉非元素节点
return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
return elem.nodeType === 1;
} ) );
};
3、 $ .grep()
作用:
返回符合 callback 函数条件的数组
源码:
//返回符合callback函数条件的数组
//elems 标签p的集合
//callback elems.nodeType===1
//invert 指定是否反转过滤结果,默认是false
grep: function( elems, callback, invert ) {
var callbackInverse,
matches = [],
i = 0,
length = elems.length, //2
callbackExpect = !invert; //true
// Go through the array, only saving the items
// that pass the validator function
//只保存符合callback函数的条件的elem(elem.nodeType===1)
for ( ; i < length; i++ ) {
//false
callbackInverse = !callback( elems[ i ], i );
//false true
if ( callbackInverse !== callbackExpect ) {
matches.push( elems[ i ] );
}
}
return matches;
},
4、有参数的 $() .remove()的简单实现:
//有参数======
$("p").remove("#pTwo")
//相当于
// jQuery.cleanData(getAll(divTwo))
pTwo.parentNode.removeChild( pTwo )
三、 $() . detach()
作用:
移除被选元素 自身 , 但保留 所有的数据、事件和子节点
注意:该方法在 不久会将删除的元素插入DOM的情况下,很有用
源码:
//移除被选元素,包括所有的文本和子节点,但会保留移除元素的副本,允许它们在以后被重新插入。
//注意那个 keepData:true
detach: function( selector ) {
return remove( this, selector, true );
},
可以看到,与 $() .remove() 的区别就是该方法第三个参数传了 true 给大 remove() 方法,即 keepData
function remove( elem, selector, keepData ) {
var node,
//remove()不带参数的话,nodes=目标元素
//$("p").remove("#pTwo") elem=$("p") selector=#pTwo
nodes = selector ? jQuery.filter( selector, elem ) : elem,
i = 0;
for ( ; ( node = nodes[ i ] ) != null; i++ ) {
//如果keepData不为true,并且node为元素节点,则清除数据和事件
if ( !keepData && node.nodeType === 1 ) {
jQuery.cleanData( getAll( node ) );
}
//如果父节点存在,则removeChild
if ( node.parentNode ) {
//$.contains:判断指定元素内是否包含另一个元素。即判断另一个DOM元素是否是指定DOM元素的后代
if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
//把所有的script标签标记为已经执行
setGlobalEval( getAll( node, "script" ) )
}
node.parentNode.removeChild( node );
}
}
return elem;
}
可以看到,在 keepData=true 的时候,会不执行 jQuery.cleanData( getAll( node ) ) 方法,并且会执行 setGlobalEval( getAll( node, "script" ) )
使用:
//无参数======
// 该方法在 不久会将删除的元素插入DOM的情况下,很有用
let removeNodeOne=$("#divTwo").detach()
//有参数======
let removeNodeTwo=$("p").detach("#pTwo")
四、关于 getAll()、jQuery.cleanData() 我们下一篇讲。。(有点累)
(完)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ReactNative源码解析-初识源码
- Spring源码系列:BeanDefinition源码解析
- Spring源码分析:AOP源码解析(下篇)
- Spring源码分析:AOP源码解析(上篇)
- 注册中心 Eureka 源码解析 —— EndPoint 与 解析器
- 新一代Json解析库Moshi源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。