jquery 獲取textarea文本值詳解

今天用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>
View Code

運行結果截圖: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;
    },
View Code

從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;
        });
    },
View Code

這裏因爲是獲取值,因此只須要看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文本節點,至於原理,還不是很清楚,等弄清楚了再說,哈哈。

相關文章
相關標籤/搜索