解密jQuery內核 DOM操做方法(二)html,text,val

回顧下幾組DOM插入有關的方法css

innerHTML 設置或獲取位於對象起始和結束標籤內的 HTML
outerHTML 設置或獲取對象及其內容的 HTML 形式html

看圖對照區別node

image

 


innerText 設置或獲取位於對象起始和結束標籤內的文本
outerText 設置(包括標籤)或獲取(不包括標籤)對象的文本jquery

image


innerText 和outerText 在讀取得時候是同樣的,只是在設置的時候outerText 會連帶標籤一塊兒替換成目標文本
firefox不支持innerText ,可是能夠用textContent做爲替代方案。api

 


nodeValue
對於文本節點,nodeValue 屬性包含文本。數組

對於屬性節點,nodeValue 屬性包含屬性值。瀏覽器

nodeValue 屬性對於文檔節點和元素節點是不可用的。app

 


jQuery封裝的方法html,text,valdom

  1. .html()用爲讀取和修改元素的HTML標籤
  2. .text()用來讀取或修改元素的純文本內容
  3. .val()用來讀取或修改表單元素的value值。

.html()

獲取集合中第一個匹配元素的HTML內容 或 設置每個匹配元素的html內容this

取值

獲取集合中第一個匹配元素的HTML內容

在一個 HTML 文檔中, 咱們可使用 .html() 方法來獲取任意一個元素的內容。 若是選擇器匹配多個元素,那麼只有第一個匹配元素的 HTML 內容會被獲取

源碼部分可見jQuery.access在屬性節點操做的時候就詳解過了,就是合併分解多個參數,細分到每個流程調用中,經過回調接收分解後的參數

可見針對nodeType === 1的節點是經過瀏覽器接口innerHTML返回須要取的值

有些瀏覽器返回的結果可能不是原始文檔的 HTML 源代碼。例如,若是屬性值只包含字母數字字符,Internet Explorer有時丟棄包裹屬性值的引號。

html: function( value ) {
        return jQuery.access( this, function( value ) {
            var elem = this[ 0 ] || {},
                i = 0,
                l = this.length;

            if ( value === undefined && elem.nodeType === 1 ) {
                return elem.innerHTML;
            }
        }, null, value, arguments.length );

設值

.html() 方法對 XML 文檔無效.

咱們可使用 .html() 來設置元素的內容,這些元素中的任何內容會徹底被新的內容取代。

此外,用新的內容替換這些元素前,jQuery從子元素刪除其餘結構,如數據和事件處理程序,防止內存溢出

if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
    !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
    value = value.replace( rxhtmlTag, "<$1></$2>" );
    try {
        for ( ; i < l; i++ ) {
            elem = this[ i ] || {};

            // Remove element nodes and prevent memory leaks
            if ( elem.nodeType === 1 ) {
                jQuery.cleanData( getAll( elem, false ) );
                elem.innerHTML = value;
            }
        }
        elem = 0;
        // If using innerHTML throws an exception, use the fallback method
    } catch( e ) {}
}

對插入的值作一下過濾處理

必須是字符串,並且不能暴行script|style|link,而且不是tr,表格等元素

最後經過innerHTML覆蓋節點,防止內存溢出須要jQuery.cleanData清理節點上的事件與數據

總結

elem.innerHTML 也就是從對象的起始位置到終止位置的所有內容,包括Html標籤。

 


.text()

獲得匹配元素集合中每一個元素的文本內容結合,包括他們的後代,或設置匹配元素集合中每一個元素的文本內容爲指定的文本內容。

.text() 在XML 和 HTML 文檔中都能使用。.text() 方法返回一個字符串,包含全部匹配元素的合併文本。  (因爲在不一樣的瀏覽器中的HTML解析器的變化,返回的文本中換行和其餘空白可能會有所不一樣。)

text: function( value ) {
    return jQuery.access( this, function( value ) {
        return value === undefined ?
            jQuery.text( this ) :
            this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
    }, null, value, arguments.length );
},

取值

 jQuery.text( this ) 實際調用Sizzle.getText

if ( typeof elem.textContent === "string" ) {
                    return elem.textContent;
                } else {
                    // Traverse its children
                    for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                        ret += getText( elem );
                    }
                }

可是實際上jQuery沒有用innerText獲取文本的值,

http://bugs.jquery.com/ticket/11153,大概就是在IE8中新節點插入會保留全部回車

因此jQuery採用了textContent獲取文本值,textContent自己是dom3規範的,能夠兼容火狐下的innerText問題

設值

考慮下,若是文本的值不單單是字符串,多是帶有標籤的

'<p>This is a test.</p>'

這種狀況下,固然就不能直接套用 elem.textContent = '<p>This is a test.</p>'

咱們必須意識到這種方法提供了必要的字符串從提供的正確的HTML中脫離出來。

jQuery這樣作, 他調用DOM 方法.createTextNode(), 一種替代的特殊字符與HTML對應(好比< 替換爲 &lt; )方法

看代碼

this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );

經過empty,先清理該節點上的事件與內容

// Prevent memory leaks
                    jQuery.cleanData( getAll( elem, false ) );
                    // Remove any remaining nodes
                    elem.textContent = "";

經過createTextNode處理,調用append

總結

.text() 在XML 和 HTML 文檔中都能使用。.text() 方法返回一個字符串,包含全部匹配元素的合併文本。  (因爲在不一樣的瀏覽器中的HTML解析器的變化,返回的文本中換行和其餘空白可能會有所不一樣。

.text() 方法不能使用在 input 元素或scripts元素上。 inputtextarea 須要使用 .val() 方法獲取或設置文本值。獲得scripts元素的值,使用.html()方法

 


.val()

獲取匹配的元素集合中第一個元素的當前值或設置匹配的元素集合中每一個元素的值。

.val()方法主要用於獲取表單元素的值,好比 input, selecttextarea

對於選擇框和複選框,您也可使用:selected:checked選擇器來獲取值,

取值

hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];

                    if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                        return ret;
                    }

                    ret = elem.value;

                    return typeof ret === "string" ?
                        // handle most common string cases
                        ret.replace(rreturn, "") :
                        // handle cases where value is null/undef or number
                        ret == null ? "" : ret;

select爲例

<select multiple="multiple"> 元素, .val()方法返回一個包含每一個選擇項的數組,若是沒有選擇性被選中,它返回null

html代碼,multiple="multiple" 多選項,若是隻是單選,只用用ele.value便可了

<select size="10" multiple="multiple" id="multipleselect" name="multipleselect">
    <option>XHTML</option>
    <option>CSS</option>
    <option>JAVASCRIPT</option>
    <option>XML</option>
    <option>PHP</option>
    <option>C#</option>
    <option>JAVA</option>
    <option>C++</option>
    <option>PERL</option>
</select>

js代碼

var p = $("#multipleselect")
     p.change(function(){
         console.log( p.val());
     });

image

針對多選的狀況,jQuery要如何處理?

引入了jQuery.valHooks,修正了在不一樣狀況下表單取值的bug,其中就有針對select的set與get的處理

image

針對多選的hack

for ( ; i < max; i++ ) {
                        option = options[ i ];

                        // IE6-9 doesn't update selected after form reset (#2551)
                        if ( ( option.selected || i === index ) &&
                            // Don't return options that are disabled or in a disabled optgroup
                            ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
                            ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {

                            // Get the specific value for the option
                            value = jQuery( option ).val();

                            // We don't need an array for one selects
                            if ( one ) {
                                return value;
                            }

                            // Multi-Selects return an array
                            values.push( value );
                        }
                    }

遍歷全部的option元素,找到對應的value

option: {
                get: function( elem ) {
                    // attributes.value is undefined in Blackberry 4.7 but
                    // uses .value. See #6932
                    var val = elem.attributes.value;
                    return !val || val.specified ? elem.value : elem.text;
                }
            }

若是是多選

values.push( value ); 

返回合集

設值

一樣的處理相似,經過jQuery.valHooks找到對應的處理hack

不然直接 this.value = val;

相關文章
相關標籤/搜索