文章出處

今天要講的這些屬性都可以用來獲取某個元素的內容,你可能會覺得不可思議,或是說上一句“喪心病狂”也。但當你看完以下內容后,會發現除outerText無用外,其他的都有各自的使用場景,不然它就真的是喪心病狂,然后我們就可以各回各家了。

innerText

引用MDN,Node.textContent上的一段話:

Internet Explorer 引入了 element.innerText,目的是相似的,不過有下面幾點不同之處:

  • textContent 會獲取所有元素的內容,包括<script><style> 元素,然而 IE 專有屬性 innerText 不會。

  • innerText 會受樣式的影響,它不返回隱藏元素的文本,但 textContent 返回。

  • 由于 innerText 受 CSS 樣式的影響,它會觸發重排(reflow),但textContent 不會。

  • 與 textContent 不同的是, 在 Internet Explorer (對于小于等于 IE11 的版本) 中對 innerText 進行修改, 不僅會移除當前元素的子節點,而且還會永久性地銷毀所有內部文本節點(由此導致無法再將這些被銷毀的文本節點插入到當前元素或任何其他元素中)。

雖然innerText是IE私有屬性,但現在很多瀏覽器也都支持這個屬性。

也許你看了以上MDN上的一段話后,心情澎湃,原來天天使用的innerText竟然有如此多的問題,但如果你看了下面這段或許又是另外一種心情了。

innerText屬性和textContent屬性除了MDN上面說的幾點以外,還有一個很大的區別,而這個區別會讓你對innerText屬性即愛又恨,這個區別就在于innerText和textContent屬性對換行的處理,來看下面這段代碼

    <div id="box"></div>
    <div id="content1"></div>
    <div id="content2"></div>
    <script>
        box.innerHTML = "a\na";
        content1.innerText =  box.innerHTML;
        content2.textContent =  box.innerHTML;
    </script>

別問我為什么不獲取元素直接使用id操作dom,懶/

以上我給box元素添加了兩個a和一個\n換行符,其解析結果如下圖

從上圖我們可以看到使用innerText設置內容的元素中莫名的出現了一個br標簽,也就是說innerText把\n當成了br來解析,我們再看使用textContent設置內容的元素,可以看到它好像多一個空格,但如果你打開源代碼會發現它不是空格,而是實實在在的換行符,不信你瞧

也就是說textContent才是解析正常的,那么為什么在頁面中看到的content2元素是一個空格呢,其實這不足為怪,來看看下面這段代碼

    <div id="content2">a
                a
    </div>

以上代碼是編輯器中的源代碼,我們每天編寫的無數行代碼中,又有無數個換行和空格吧?你應該看到過它的效果吧?HTML對換行和空格不敏感!!!多個換行或空格只會當成是一個空格。

那么有沒有辦法解決?有!而且用CSS就可以做到了,想讓瀏覽器對某個元素原樣輸出,可以給它加以下這段CSS

white-space: pre;

這段css的意思是,將此元素按照在源代碼中的樣子進行輸出,也就是你代碼怎么寫的,它就怎么輸出(保留空格和換行符)。除了用css以外也還可以使用pre元素來達到同樣的效果。

textContent和innerText的區別不僅僅在設置內容的時候會出現,在獲取的時候一樣也會出現,比如下面這段

    <div id="box"></div>
    <div id="content1"></div>
    <div id="content2"></div>
    <script>
        box.innerHTML = "a<div></div>a";
        content1.innerHTML =  box.innerText;
        content2.innerHTML =  box.textContent;
    </script>

效果如下圖

使用innerText獲取的內容將<div></div>當成了一個換行,使用textContent獲取內容的元素一切正常。如果我們將<div></div>換成<br>,你會發現更坑,它把每個<br>都當成了一個換行,效果如下

你沒有看錯就是兩個換行符,源代碼如下

    <div id="box"></div>
    <div id="content1"></div>
    <div id="content2"></div>
    <script>
        box.innerHTML = "a<br><br>a";
        content1.innerHTML =  box.innerText;
        content2.innerHTML =  box.textContent;
    </script>

也許你會想,如果使用兩個div元素,那么是不是也會出現兩個換行符呢?結果令你失望,只有當是<br>才會。

它們的區別大概就是如此了,所以以后在選擇使用innerText和textContent的時候,請慎重啊。

textContent

用來設置或是獲取某個元素內所有文本內容,包括子元素中的內容,如果是設置,則原本的子元素會被同被替換掉。

innerHTML

用來設置或是獲取某個元素內所有元素及內容,包括子元素。當內容都是文本的時候,可以把這個屬性當做textContent屬性來用。

outerHTML

outerHTML和innerHTML很像,它們的唯一區別就是outerHTML包括自身元素而innerHTML不包括自身元素。

nodeValue

nodeValue和textContent很像,它們都是用來獲取某個元素中的內容的,不過nodeValue并不能直接操作某個dom元素,它只能用來獲取某段文本節點中的內容,知道你肯定對這個不熟,演示一下給你看。

    <div id="box">javascript<span>html</span></div>
    <div id="content1"></div>
    <script>
        content1.innerHTML =  box.childNodes[0].nodeValue;
    </script>

在使用nodeValue之前,我們需要先使用childNodes獲取box中的所有節點集合,childNodes返回的是一個NodeList數組,如下圖

雖然NodeList數組返回所有子節點,不過我們只能對文本節點使用nodeValue屬性噢,假如你想把html賦給content1,是不能直接通過box.childNodes[1].nodeValue來獲取的,因為box.childNodes[1]是元素,而如果想獲取span中的文本節點,我們得像下面這樣

    <div id="box">javascript<span>html</span></div>
    <div id="content1"></div>
    <script>
        content1.innerHTML =  box.childNodes[1].childNodes[0].nodeValue;
    </script>

效果如下

雖然你可能會覺得以上那段代碼寫著很煩,但如果你想細致化的操作文本節點,這個屬性對你來說就非常有用了。

outerText

看了以上內容,你肯定想到了,這個outerText和outerHTML有同樣的功能它們都包括自身,不同的是outerText獲取的是元素內容,而outerHTML獲取到的內容包括元素。

那么為什么我一開始說outerText無用呢,因為它能做的事,textContent、innerText和innerHTML都可以做。

那么為什么textContent、innerText和innerHTML都可以做outerText的事呢?

<div>javascript</div>

以上這段代碼使用div包含了一段文本節點。

因為文本節點不可能單獨使用,也就是說所有文本節點都有父元素!既然有父元素那么文本節點就只能是屬于某個元素的子節點,又因為是子節點,textContent、innerText和innerHTML自然也就能使用啦,所有這個outerText也就只能做個有名無份的主了。

注意:就算文本節點是屬于元素自身的,那它也還是元素的子節點!

完。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()