您好,登錄后才能下訂單哦!
怎么在jQuery中實現一個text()方法?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
jquery是一個簡潔而快速的JavaScript庫,它具有獨特的鏈式語法和短小清晰的多功能接口、高效靈活的css選擇器,并且可對CSS選擇器進行擴展、擁有便捷的插件擴展機制和豐富的插件,是繼Prototype之后又一個優秀的JavaScript代碼庫,能夠用于簡化事件處理、HTML文檔遍歷、Ajax交互和動畫,以便快速開發網站。
一、有這樣一段 html
<div class="divOne"> <p>嘿嘿嘿</p> </div> <div class="divOne"> <p>哈哈哈</p> </div>
二、jQuery 的 text() 方法
(1)當直接調用 $().text()
時,.text()的作用是(循環)讀取(多個)目標元素的textContent/nodeValue
簡單實現:
function readText(elem) { let node, ret = "", i = 0, nodeType = elem.nodeType console.log(nodeType,'nodeType22') //如果selector是類的話,會有多個目標元素,此時需要分別單個循環 //比如document.querySelectorAll('.divOne').nodeType ->undefined if (!nodeType) { while ((node = elem[i++])) { //單個獲取 ret += readText(node) } } //元素節點,文檔節點,文檔碎片 else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { //如果目標元素的內容是文本,則直接返回 if (typeof elem.textContent === "string") { /*jQuery沒有用innerText獲取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在IE8中新節點插入會保留所有回車。 所以jQuery采用了textContent獲取文本值, textContent本身是dom3規范的,可以兼容火狐下的innerText問題。*/ return elem.textContent } //如果節點內容不是文本,則循環子節點,并依次獲取它們的文本節點 else { for (elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += readText(elem) } } } //文本節點、一個文檔的CDATA部分(沒遇到過這個) else if (nodeType === 3 || nodeType === 4) { //返回節點值 return elem.nodeValue; } //nodeType:注釋節點 8,處理指令 7 //text()方法不處理這兩個類型節點 return ret }
(2)當調用$().text(value)
時,.text(value)的作用是為每一個符合條件的目標元素的textContent設置為 value
簡單實現:
writeText():
function writeText(value) { let elem, i = 0; //先清空目標元素的內容 customEmpty.call(this) //循環 for (; (elem = this[i]) != null; i++) { //元素節點,文檔碎片,文檔節點 if (elem.nodeType === 1 || elem.nodeType === 11 || elem.nodeType === 9) { // text()方法不會解析標簽 elem.textContent = value; } } //return this 方便鏈式調用 return this }
customEmpty():
function customEmpty() { let elem, i = 0; //注意for循環的寫法 for (; (elem = this[i]) != null; i++) { //如果是元素節點的話,清空該節點的所有內容 if (elem.nodeType === 1) { elem.textContent = ""; } } return this; }
(3)源碼實現
源碼:
jQuery.text()總體:
//源碼6152行 text: function( value ) { return access( this, function( value ) { return value === undefined ? //讀 //如果直接調用text()的話,就調用Sizzle.getText jQuery.text( this ) : //寫 //循環 this.empty().each( function() { //先清空目標元素的內容,然后再賦值 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { console.log(value,'value6159') //如果包含標簽的話,需要用html()方法,text()方法不會解析標簽 /*jQuery沒有用innerText獲取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在IE8中新節點插入會保留所有回車。 所以jQuery采用了textContent獲取文本值, textContent本身是dom3規范的,可以兼容火狐下的innerText問題。*/ this.textContent = value; } } ) }, null, value, arguments.length ); },
源碼解析:
① 調用text(),實際上是調用access()
也就是說:調用jQuery.access()
相當于調用了fn.call( elems, value )
,即自定義的方法jQuery.access(this, function(value) {xxx})
② .text()的情況調用這部分源碼:
jQuery.text()
調用的其實是Sizzle.getText()
:
//源碼2833行 jQuery.text = Sizzle.getText; Sizzle.getText(): //源碼1642行 getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { while ( (node = elem[i++]) ) { // Do not traverse comment nodes ret += getText( node ); } } //元素節點、文檔節點、文檔碎片 else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) //如果目標元素的子節點是文本節點,則直接返回它的textContent if ( typeof elem.textContent === "string" ) { /*jQuery沒有用innerText獲取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在IE8中新節點插入會保留所有回車。 所以jQuery采用了textContent獲取文本值, textContent本身是dom3規范的,可以兼容火狐下的innerText問題。*/ return elem.textContent; } //如果子節點不是文本節點,則循環子節點,并依次獲取它們的文本節點 else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } //文本節點、一個文檔的CDATA部分(沒遇到過這個) else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; };
③ .text(value)的情況調用這部分源碼:
jQuery.text(value):
//寫 //循環 this.empty().each( function() { //先清空目標元素的內容,然后再賦值 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { console.log(value,'value6159') //如果包含標簽的話,需要用html()方法,text()方法不會解析標簽 /*jQuery沒有用innerText獲取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在IE8中新節點插入會保留所有回車。 所以jQuery采用了textContent獲取文本值, textContent本身是dom3規范的,可以兼容火狐下的innerText問題。*/ this.textContent = value; } } )
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; },
④ 總結
$(".divOne").text()
的本質:
(1)節點內容是文本,返回$(".divOne")[i].textContent
(2)節點內容不是文本,循環返回$(".divOne")[i].element[j].textContent
(3)節點內容是文本節點或一個文檔的CDATA部分,則返回$(".divOne")[i]. nodeValue
$(".divOne").text("Hello <b>world</b>!")
的本質:
(1)jQuery.cleanData()
(2)$(".divOne")[i].textContent = ""
(3)$(".divOne")[i].textContent="Hello world!"
注意:text() 不會去解析 html 標簽!
參考:http://api.jquery.com/text/
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jQuery之text()</title> </head> <body> <script src="jQuery.js"></script> <div class="divOne"> <!--<p id="divTwo">嘿嘿嘿</p>--> <p>嘿嘿嘿</p> </div> <div class="divOne"> <p>哈哈哈</p> </div> <input type="text" id="inputOne"> <script> function readText(elem) { let node, ret = "", i = 0, nodeType = elem.nodeType console.log(nodeType,'nodeType22') //如果selector是類的話,會有多個目標元素,此時需要分別單個循環 //比如document.querySelectorAll('.divOne').nodeType ->undefined if (!nodeType) { while ((node = elem[i++])) { //單個獲取 ret += readText(node) } } //元素節點,文檔節點,文檔碎片 else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { //如果目標元素的內容是文本,則直接返回 if (typeof elem.textContent === "string") { /*jQuery沒有用innerText獲取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在IE8中新節點插入會保留所有回車。 所以jQuery采用了textContent獲取文本值, textContent本身是dom3規范的,可以兼容火狐下的innerText問題。*/ return elem.textContent } //如果節點的內容不是文本,則循環子節點,并依次獲取它們的文本節點 else { for (elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += readText(elem) } } } //文本節點、一個文檔的CDATA部分(沒遇到過這個) else if (nodeType === 3 || nodeType === 4) { //返回節點值 return elem.nodeValue; } //nodeType:注釋節點 8,處理指令 7 //text()方法不處理這兩個類型節點 return ret } function customEmpty() { let elem, i = 0; //注意for循環的寫法 for (; (elem = this[i]) != null; i++) { //如果是元素節點的話,清空該節點的所有內容 if (elem.nodeType === 1) { elem.textContent = ""; } } return this; } function writeText(value) { let elem, i = 0; //先清空目標元素的內容 customEmpty.call(this) //循環 for (; (elem = this[i]) != null; i++) { //元素節點,文檔碎片,文檔節點 if (elem.nodeType === 1 || elem.nodeType === 11 || elem.nodeType === 9) { // text()方法不會解析標簽 elem.textContent = value; } } //return this 方便鏈式調用 return this } function customText(value) { return value === undefined ? //讀 readText(this) : //寫 writeText.call(this, value) } customText.call(document.querySelectorAll('.divOne')) customText.call(document.querySelectorAll('.divOne'),"Hello <b>world</b>!") // let p=document.createElement('p') // p.innerText='哈哈哈' console.log($(".divOne").text()) // customText.call(document.querySelectorAll('.divOne')) // console.log(document.querySelectorAll('.divOne').nodeType,'childnode81') // console.log(document.querySelectorAll('.divOne')[0].textContent,'childnode81') // $("#divOne").text('<p>aaaa</p>') // console.log(document.querySelector("#divTwo")) </script> </body> </html>
關于怎么在jQuery中實現一個text()方法問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。