nodeValue กับ innerHTML และ textContent วิธีการเลือก?


129

ฉันใช้ js ธรรมดาเพื่อแก้ไขข้อความภายในขององค์ประกอบป้ายกำกับและฉันไม่แน่ใจว่าเหตุใดฉันควรใช้ innerHTML หรือ nodeValue หรือ textContent ฉันไม่จำเป็นต้องสร้างโหนดใหม่หรือเปลี่ยนองค์ประกอบ HTML หรืออะไรเลย - เพียงแค่แทนที่ข้อความ นี่คือตัวอย่างของรหัส:

var myLabel = document.getElementById("#someLabel");
myLabel.innerHTML = "Some new label text!"; // this works

myLabel.firstChild.nodeValue = "Some new label text!"; // this also works.

myLabel.textContent = "Some new label text!"; // this also works.

ฉันดูแหล่งที่มา jQuery และใช้ nodeValue เพียงครั้งเดียว แต่ innerHTML และ textContent หลายครั้ง จากนั้นฉันพบการทดสอบ jsperf ซึ่งบ่งชี้ว่า firstChild.nodeValue นั้นเร็วกว่ามาก อย่างน้อยนั่นคือสิ่งที่ฉันตีความหมายถึง

ถ้า firstChild.nodeValue เร็วกว่ามากสิ่งที่จับได้คืออะไร? มันไม่ได้รับการสนับสนุนอย่างกว้างขวาง? มีปัญหาอื่น ๆ อีกหรือไม่?

คำตอบ:


156

ความแตกต่างระหว่าง textContent / innerText / innerHTML บน MDN

และคำตอบ Stackoverflow เกี่ยวกับ innerText / nodeValue

สรุป

  1. innerHTMLแยกวิเคราะห์เนื้อหาเป็น HTML ดังนั้นจึงใช้เวลานานกว่า
  2. nodeValueใช้ข้อความตรงไม่แยกวิเคราะห์ HTML และเร็วกว่า
  3. textContentใช้ข้อความตรงไม่แยกวิเคราะห์ HTML และเร็วกว่า
  4. innerText นำรูปแบบมาพิจารณา จะไม่ได้รับข้อความที่ซ่อนไว้เช่น

innerTextไม่มีอยู่ใน firefox จนถึง FireFox 45 ตามcaniuseแต่ตอนนี้ได้รับการสนับสนุนในเบราว์เซอร์หลักทั้งหมด


4
เอ่อnodeValueไม่ได้แยกวิเคราะห์ html ด้วย
Bergi

1
"การใช้ textContent สามารถป้องกันการโจมตี XSS" developer.mozilla.org/en-US/docs/Web/API/Node/textContent
DRP

58

.textContentเอาท์พุทtext/plainในขณะที่เอาท์พุท.innerHTMLtext/html

ตัวอย่างด่วน:

var example = document.getElementById('exampleId');

example.textContent = '<a href="https://google.com">google</a>';

เอาต์พุต: <a href="http://google.com"> google </a>

example.innerHTML = '<a href="https://google.com">google</a>';

เอาต์พุต: Google

คุณสามารถดูได้จากตัวอย่างแรกที่text/plainเบราว์เซอร์ไม่แยกวิเคราะห์ผลลัพธ์ประเภทและผลลัพธ์ในการแสดงเนื้อหาทั้งหมด ผลลัพธ์ของประเภทtext/htmlจะบอกให้เบราว์เซอร์แยกวิเคราะห์ก่อนที่จะแสดง

MDN innerHTML , MDN textContent , MDN nodeValue


7

ทั้งสองฉันรู้ดีและมีการทำงานร่วมกับ innerHTML และtextContent

ฉันใช้textContentเมื่อต้องการเปลี่ยนข้อความของย่อหน้าหรือหัวเรื่องดังนี้:

var heading = document.getElementById('heading')
var paragraph = document.getElementById('paragraph')

setTimeout(function () {
  heading.textContent = 'My New Title!'
  paragraph.textContent = 'My second <em>six word</em> story.'
}, 2000)
em { font-style: italic; }
<h1 id="heading">My Title</h1>
<p id="paragraph">My six word story right here.</p>

ดังนั้นtextContentเพียงแค่เปลี่ยนข้อความ แต่ไม่ได้แยกวิเคราะห์ HTML อย่างที่เราบอกได้จากแท็กที่ปรากฏในข้อความธรรมดาในผลลัพธ์ที่นั่น

หากเราต้องการแยกวิเคราะห์ HTML เราใช้innerHTMLดังนี้:

var heading = document.getElementById('heading')
var paragraph = document.getElementById('paragraph')

setTimeout(function () {
  heading.innerHTML = 'My <em>New</em> Title!'
  paragraph.innerHTML = 'My second <em>six word</em> story.'
}, 2000)
em { font-style: italic; }
<h1 id="heading">My Title</h1>
<p id="paragraph">My six word story right here.</p>

ดังนั้นตัวอย่างที่สองจะแยกวิเคราะห์สตริงที่ฉันกำหนดให้กับคุณสมบัติinnerHTMLขององค์ประกอบ DOM เป็น HTML

สิ่งนี้ยอดเยี่ยมและเป็นช่องโหว่ด้านความปลอดภัยขนาดใหญ่ :)

(ค้นหา XSS หากคุณต้องการทราบเกี่ยวกับความปลอดภัยสำหรับสิ่งนี้)


3

innerTextคือสิ่งที่คุณจะได้รับหากคุณเลือกข้อความและคัดลอก องค์ประกอบที่ไม่แสดงผลจะไม่มีอยู่ใน innerText

textContentเป็นการเชื่อมต่อค่าของTextNodes ทั้งหมดในแผนผังย่อย ไม่ว่าจะแสดงผลหรือไม่ก็ตาม

นี่คือโพสต์ที่ยอดเยี่ยมที่ให้รายละเอียดความแตกต่าง

innerHTMLไม่ควรรวมอยู่ในการเปรียบเทียบกับ innerText หรือ textContent เนื่องจากมันแตกต่างกันโดยสิ้นเชิงและคุณควรรู้ว่าทำไม :-) ดูแยกกัน


1
สิ่งที่คุณพูดเกี่ยวกับ innerHTML นั้นชัดเจนสำหรับฉันมากจนฉันแน่ใจว่าไม่เข้าใจว่าทำไมมีหลายคนที่ไม่เข้าใจ
user34660

1

[หมายเหตุ: โพสต์นี้เป็นข้อมูลเพิ่มเติมเกี่ยวกับการแบ่งปันข้อมูลเฉพาะที่อาจช่วยใครบางคนได้มากกว่าการบอกให้คนอื่นทำอะไร]

เผื่อมีคนสงสัยว่าวันนี้เร็วที่สุด: https://jsperf.com/set-innertext-vs-innerhtml-vs-textcontent & https://jsperf.com/get-innertext-vs-innerhtml-vs-textcontent ( สำหรับการทดสอบครั้งที่สองเนื้อหาของสแปนเป็นข้อความธรรมดาผลลัพธ์อาจเปลี่ยนแปลงไปตามเนื้อหา)

ดูเหมือนว่า.innerHtmlจะเป็นผู้ชนะที่ยิ่งใหญ่ในแง่ของความเร็วที่แท้จริง!

(หมายเหตุ: ฉันพูดถึงความเร็วที่นี่เท่านั้นคุณอาจต้องมองหาเกณฑ์อื่น ๆ ก่อนที่จะเลือกว่าจะใช้อันไหน!)


0

Element.innerHTML เป็นsetหรือgetโค้ด HTML ขององค์ประกอบ

เช่นเรามี<h1>แท็กและสไตล์ที่ชัดเจน:

<h1 id="myHeader" style="color: green"><strong>My Header</strong> Normal Text</h1> เพื่อให้getเนื้อหาขององค์ประกอบมี id เท่ากับ "myHeader" เราจะดำเนินการเช่นเดียวกัน:

var element = document.getElementById("myHeader");
element.innerHTML

ผลตอบแทน:

<strong>My Header</strong> Normal Text`

หากต้องการ "ตั้งค่า" เนื้อหาใหม่ (ค่า) สำหรับองค์ประกอบนี้รหัสจะอยู่ที่นี่:

Element.innerHTML = "My Header My Text";

ดังนั้นคุณสมบัตินี้ไม่เพียง แต่ใช้งานได้กับข้อความธรรมดาเท่านั้น แต่ยังมุ่งเป้าไปที่การส่งผ่านหรือคัดลอกโค้ด HTML

=> เราไม่ควรใช้มัน

อย่างไรก็ตามโปรแกรมเมอร์หลายคน (รวมถึงตัวฉันเอง) ใช้แอตทริบิวต์นี้เพื่อแทรกข้อความลงในหน้าเว็บและวิธีนี้มีความเสี่ยงที่อาจเกิดขึ้น:

  1. การดำเนินการที่ไม่ถูกต้อง: การแทรกแต่ละข้อความบางครั้งจะลบโค้ด HTML อื่น ๆ ทั้งหมดขององค์ประกอบที่แทรก
  2. เพื่อความปลอดภัย: แน่นอนว่าสองตัวอย่างข้างต้นไม่เป็นอันตรายอย่างสมบูรณ์แม้ว่าการใช้แท็กจะยังไม่มีปัญหาเนื่องจากมาตรฐาน HTML5 ได้ป้องกันไม่ให้เรียกใช้บรรทัดคำสั่งภายในแท็ก เมื่อแทรกลงในหน้าเว็บผ่านแอตทริบิวต์ innerHTML ดูกฎข้อนี้ที่นี่

เพราะเหตุผลนี้ใช้ไม่แนะนำเมื่อใส่ข้อความธรรมดาแทนการใช้งานinnerHTML ทรัพย์สินจะไม่เข้าใจว่ารหัสผ่านที่คุณเป็นไวยากรณ์ HTML แต่เพียงข้อความ 100% ไม่มากและไม่น้อยtextContenttextContent

ผลลัพธ์จะกลับมาหากใช้textContentในตัวอย่างข้างต้น:

My Header My Text
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.