獲取 DOM 內容的 API 接口

rgzr3099 7年前發布 | 36K 次閱讀 API jQuery Ajax框架

Web 開發者可能會使用 jQuery .html() .text() 方法來設置 DOM 內容,但他們的實現仍然依賴于 DOM API。 本文來梳理一下這些用來獲取 DOM 內容的 DOM 屬性(attribute), 比較它們的區別: innerHTML , outerHTML , innerText , outerText , text , textContent , 以及 jQuery 中 .html() 和 .text() 的實現。

innerHTML/outerHTML

outerHTML innerHTML DOM 屬性用來設置 DOM 的 HTML 內容。 其中 innerHTML 返回元素內容的 HTML 片段,而 outerHTML 返回的 HTML 片段則包括元素本身、以及元素內容的。 其中 innerH 常常用于清空元素內容。

document.body.innerHTML = '';

需要注意 innerHTMl 設置的腳本內容將不會被執行,參考 在 DOM 中動態插入并執行腳本

innerText/outerText

與 innerHTML , outerHTML 相同,inner 只會設置內容而 outer 會更改整個元素。 不同的是, innerText 與 outerText 則用來獲取和設置渲染后的結果。 例如設置的 HTML 特殊字符會被轉義,換行會被解析為 <br/> 。例如:

document.body.innerText = '<h2>header</h2>\nparagraph'

的渲染結果為:

<h2>header</h2><br>paragraph

利用 innerText 可以方便地進行 HTML 轉義:

function escape(str){
  var el = document.createElement('div');
  el.innerText = str;
  return el.innerHTML;
}

// 返回 <h2 id="foo">
escape('<h2 id="foo">');

text/textContent

textContent 與 innerText 表現相似,但有一些細節不同:

  • textContent 是定義在 Node 上的,Element 繼承了該屬性。
  • textContent 可以獲取不渲染的內容而 innerText 不可以。包括 <style> , <script> , 以及被 CSS 隱藏的元素。
  • 因 innerText 排除了隱藏元素,它會引起重排(Reflow)。
  • IE11 及以下的 innerText 會銷毀被移除的元素,而 textContent 不會。

text 只在特定的幾個元素上有定義,比如 <a> 和 <script> :

  • <a> 元素的 text 用來設置其文本內容。其表現完全等同于 textContent :

    The text IDL attribute, on getting, must return the same value as the textContent IDL attribute on the element, and on setting, must act as if the textContent IDL attribute on the element had been set to the new value. – W3C HTML5

  • <script> 元素的 text 用來設置其腳本的內容,這時完全等同于 textContent , innerText , innerHTML 。

jQuery .html()

jQuery 的 .html() 用來設置 HTML 元素的 HTML 內容。 不同于 innherHTML ,jQuery 的 .html() 會執行字符串中的腳本。 幾乎所有操作 DOM 內容的 jQuery 方法都有這一行為,包括 .after() , .append() , .before() 等等。

當然這不是 Magic,jQuery 在設置 innerHTML 的同時,找到了里面所有的 <script> 并進行強制加以執行。 在 .html() 的定義在 /src/manipulation.js 中, 它調用了 .append() 來進行進行 DOM 操作,最終調用到 domManip( collection, args, callback, ignored ) 函數:

function domManip( collection, args, callback, ignored ) {
    // ...
    if ( hasScripts ) {
        // ...
        if ( node.src ) {
            // Optional AJAX dependency, but won't run scripts if not present
            if ( jQuery._evalUrl ) {
                jQuery._evalUrl( node.src );
            }
        } else {
            DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
        }
    }
}

這里調用了 DOMEval 來強制執行腳本,其代碼在 /src/core/DOMEval.js 中:

function DOMEval( code, doc ) {
    doc = doc || document;

    var script = doc.createElement( "script" );

    script.text = code;
    doc.head.appendChild( script ).parentNode.removeChild( script );
}

.appendChild() 并立即 .removeChild() 會導致立即執行(以及必要的下載)腳本。對于動態執行腳本在 DOM 中動態插入并執行腳本 一文有詳細討論。

jQuery .text()

jQuery .text() 就非常簡單,它的實現只有 11 行, 使用的 DOM API 正是上文中討論的 textContent :

text: function( value ) {
    return access( this, function( value ) {
        return value === undefined ?
            jQuery.text( this ) :
            this.empty().each( function() {
                if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                    this.textContent = value;
                }
            } );
    }, null, value, arguments.length );
},

擴展閱讀

 

來自:http://harttle.com/2017/01/29/dom-content-interface.html

 

 本文由用戶 rgzr3099 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!