前言: 跟 當我呼叫了$()
.append()後,jQuery內部發生了什麼? 一樣,replaceWith() 會經過 domManip()
和 buildFragment()
的洗禮,最後呼叫原生JS的方法來實現。
所以,本文只講述 jQuery 中最後對 replaceWith() 處理的相關程式碼。
想了解domManip()
和 buildFragment()
的,請看 當我呼叫了$()
.append()後,jQuery內部發生了什麼?
一、示例程式碼
<body>
<script src="jQuery.js"></script>
<div id="divTwo">
<p id="pTwo">這是divTwo</p>
</div>
<div id="divOne">
<p>這是divOne</p>
</div>
<script>
let divOne = document.querySelector("#divOne")
let divTwo = document.querySelector("#divTwo")
let pTwo = document.querySelector("#pTwo")
// ===========replaceWith==============
//注意:removedNode指向已經被移除的divTwo
let removedNode=$("#divTwo").replaceWith("<span>永遠</span>")
console.log(removedNode,'removedNode21')
//======相當於=====
let spanA=document.createElement("span")
spanA.innerText="永遠"
divTwo.parentNode.replaceChild(spanA,divTwo)
// ==============unwrap================
$("#pTwo").unwrap()
//======相當於=====
let pTwoFather=pTwo.parentNode
if(pTwoFather.nodeName.toLowerCase()!=='body'){
pTwoFather.parentNode.replaceChild(pTwo,pTwoFather)
}
</script>
</body>
複製程式碼
二、$()
.replaceWith()
作用:
把被選元素替換為新的內容
注意:$()
.replaceWith() 指向已經被移除的元素。
原始碼:
// 原始碼6324行
// 把被選元素替換為新的內容
replaceWith: function() {
var ignored = [];
// Make the changes, replacing each non-ignored context element with the new content
return domManip( this, arguments, function( elem ) {
//獲取選擇器的父節點
var parent = this.parentNode;
//$.inArray() 函式用於在陣列中查詢指定值,並返回它的索引值(如果沒有找到,則返回-1)
//inArray() 可以看成是indexOf()
//如果ignored陣列中沒有目標元素的話
if ( jQuery.inArray( this, ignored ) < 0 ) {
//清除目標元素的事件
jQuery.cleanData( getAll( this ) );
if ( parent ) {
//原生JS方法replaceChild(newnode,oldnode) 將某子節點替換成另一個
parent.replaceChild( elem, this );
}
}
// Force callback invocation
}, ignored );
}
複製程式碼
解析:
① 先找到目標元素的父節點 this.parentNode
② 使用 $
.cleanData() 清除目標元素上的 事件和快取jQuery.cleanData( getAll( this ) )
③ 當父節點存在時,父節點調動replaceChild()
,將待替換的元素 替換到 目標元素上
簡單實現:
//注意:removedNode指向已經被移除的divTwo
let removedNode=$("#divTwo").replaceWith("<span>永遠</span>")
console.log(removedNode,'removedNode21')
//======相當於=====
let spanA=document.createElement("span")
spanA.innerText="永遠"
divTwo.parentNode.replaceChild(spanA,divTwo)
複製程式碼
三、$()
.inArray()
作用:
檢視元素在陣列中的位置
原始碼:
//原始碼453行,檢視元素在陣列中的位置
inArray: function( elem, arr, i ) {
//indexOf:array.indexOf
return arr == null ? -1 : indexOf.call( arr, elem, i );
},
複製程式碼
四:$()
.unwrap()
作用:
移除被選元素的父元素(父節點是body則無效)
原始碼:
//原始碼9798行
//移除被選元素的父元素(父節點是body則無效)
unwrap: function( selector ) {
//選中目標元素的父節點(除了body)
this.parent( selector ).not( "body" ).each( function() {
//this表示父節點
//即父節點被它的子節點替換
jQuery( this ).replaceWith( this.childNodes );
} );
return this;
}
複製程式碼
解析:
是在目標元素的爺爺節點上呼叫 replaceWith() 方法,將父節點替換成目標節點。
注意:目標元素的父節點是body
的話,$().unwrap()
方法無效。
簡單實現:
$("#pTwo").unwrap()
//======相當於=====
let pTwoFather=pTwo.parentNode
if(pTwoFather.nodeName.toLowerCase()!=='body'){
pTwoFather.parentNode.replaceChild(pTwo,pTwoFather)
}
複製程式碼
五、$()
.parent()
作用:
返回被選元素的直接父元素
原始碼:
//原始碼3245行
//11表示文件碎片
//返回被選元素的直接父元素
parent: function( elem ) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
複製程式碼
這個一看就懂,就不解釋了
(完)