今天用jquery獲取textarea文本值,遇到這麼一個問題:javascript
一開始用val()方法報錯,後面使用text(),能夠運行,可是獲取的值永遠爲空,最後在改爲val(),能夠正常使用。html
因而乎:爲了把這個問題弄清楚,開始了遙遠的解讀jQuery源碼之旅java
步驟:node
1. 給textarea設置默認值,分別輸出text()和value()值jquery
2. 改變textarea的文本值,在分別輸出text()和value()值app
例子:dom
代碼:ide
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>dom屬性測試</title> 6 </head> 7 <body> 8 <div id="js-div"> 9 <textarea id="js-textarea" >hhhh</textarea> 10 <button type="button" id="js-button">顯示文本</button> 11 12 <input value="hello world" id="js-input"> 13 </div> 14 <script type="text/javascript" src="../demo-plugin/public/js/jquery.js"></script> 15 <script type="text/javascript"> 16 var $textArea = $('#js-textarea'), 17 textArea = $textArea.val(); 18 19 console.log('val:',textArea); 20 console.log('text:',$textArea.text()); 21 22 $('#js-button').click(function () { 23 24 console.log('changed val:',$textArea.val()); 25 console.log('changed text:',$textArea.text()); 26 }); 27 </script> 28 </body> 29 </html>
運行結果截圖:oop
從上面的例子能夠看出:測試
1. text()方法只可以獲取到textarea的初始化文本值。
2. val() 方法不只能夠獲取textarea的初始化文本值,當文本值改變時,也能正常獲取到。
接下來,看jquery源碼:
1. text()方法:
text: function( text ) { if ( typeof text != "object" && text != null ) return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); var ret = ""; jQuery.each( text || this, function(){ jQuery.each( this.childNodes, function(){ if ( this.nodeType != 8 ) ret += this.nodeType != 1 ? this.nodeValue : jQuery.fn.text( [ this ] ); }); }); return ret; },
從jquery源碼中能夠看出,text()方法是經過遍歷元素的childNodes,獲取每一個子節點的nodeValue,拼接成字符串返回。
2. val()方法:
val: function( value ) { if ( value == undefined ) { if ( this.length ) { var elem = this[0]; // We need to handle select boxes special if ( jQuery.nodeName( elem, "select" ) ) { var index = elem.selectedIndex, values = [], options = elem.options, one = elem.type == "select-one"; // Nothing was selected if ( index < 0 ) return null; // Loop through all the selected options for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { var option = options[ i ]; if ( option.selected ) { // Get the specifc value for the option value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; // We don't need an array for one selects if ( one ) return value; // Multi-Selects return an array values.push( value ); } } return values; // Everything else, we just grab the value } else return (this[0].value || "").replace(/\r/g, ""); } return undefined; } return this.each(function(){ if ( this.nodeType != 1 ) return; if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) this.checked = (jQuery.inArray(this.value, value) >= 0 || jQuery.inArray(this.name, value) >= 0); else if ( jQuery.nodeName( this, "select" ) ) { var values = value.constructor == Array ? value : [ value ]; jQuery( "option", this ).each(function(){ this.selected = (jQuery.inArray( this.value, values ) >= 0 || jQuery.inArray( this.text, values ) >= 0); }); if ( !values.length ) this.selectedIndex = -1; } else this.value = value; }); },
這裏因爲是獲取值,因此只須要看if(value == 'undefined'){...}分支,
根據代碼,能夠知道,當元素爲input時,走的是else 分支,由語句:
return (this[0].value || "").replace(/\r/g, "");
能夠看出,返回的元素的value值。
說了一堆,必定很疑惑分析這個有什麼用,別走開,接下來更精彩:
頁面初始化時:打印$('#js-textarea'),看看控制檯都輸出什麼東西:
上面兩張圖能夠看出,在爲改變textarea的文本值時,textarea的value屬性值=初始值,nodeValue值爲null,text()方法返回的是childNodes裏面每一個節點的nodeValue值拼接起來的字符串,注意區分。
接着看childNodes裏面的內容:
能夠看出,textarea有一個text文本節點,這個文本節點的nodeValue = 初始值。
接下來:改變文本框的文本值,輸出$('#js-textarea'),見證奇蹟的時刻到了:
先看textarea的value屬性值:
value值改變,那麼子節點text的nodeValue值有沒有變化呢,看截圖
從上圖能夠看出:很遺憾,textarea的childNodes裏面text文本節點的nodeValue值並無發生變化。
爲何會出現這個現象,我也還不知道,不過這個測試結果說明了,爲何val()方法能夠正常取值,而text()取值會出現問題。
後記:通過研究,發現自閉合標籤childNodes長度爲0,而其餘標籤至少有一個text文本節點,至於原理,還不是很清楚,等弄清楚了再說,哈哈。