ฉันมีรหัส JavaScript ที่ทำงานใน IE ที่มีสิ่งต่อไปนี้:
myElement.innerText = "foo";
อย่างไรก็ตามดูเหมือนว่าคุณสมบัติ 'innerText' จะไม่ทำงานใน Firefox Firefox มีอะไรบ้างที่เทียบเท่า? หรือมีคุณสมบัติข้ามเบราว์เซอร์ทั่วไปที่สามารถใช้งานได้มากกว่านี้?
ฉันมีรหัส JavaScript ที่ทำงานใน IE ที่มีสิ่งต่อไปนี้:
myElement.innerText = "foo";
อย่างไรก็ตามดูเหมือนว่าคุณสมบัติ 'innerText' จะไม่ทำงานใน Firefox Firefox มีอะไรบ้างที่เทียบเท่า? หรือมีคุณสมบัติข้ามเบราว์เซอร์ทั่วไปที่สามารถใช้งานได้มากกว่านี้?
คำตอบ:
Firefox ใช้คุณสมบัติtextContent ที่สอดคล้อง กับW3C
ฉันเดาว่า Safari และ Opera รองรับคุณสมบัตินี้เช่นกัน
innerTextเท่านั้นและคาดว่ามันจะทำงานได้
innerTextคืออย่างสุดซึ้งที่แตกต่างกันจากtextContentและที่จริงเป็นประโยชน์อย่างมาก (น่าแปลกใจจากการเป็นมุมแหลม IE สันนิษฐานว่า ... ): innerTextพยายามที่จะให้การประมาณการว่าข้อความที่ถูกนำเสนอจริงในเบราว์เซอร์ทั้งหมดแตกต่างtextContentซึ่งผลตอบแทนเพียงเกี่ยวกับtag- ปล้นมาร์กอัปเพิ่มมูลค่าน้อยหรือมีปัญหาพิเศษ (เช่นการสูญเสียขอบเขตของคำ)
อัปเดต : ฉันเขียนบล็อกโพสต์ที่มีรายละเอียดแตกต่างกันทั้งหมดดีกว่ามาก
Firefox ใช้มาตรฐาน W3C Node::textContentแต่พฤติกรรมนั้นแตกต่าง "เล็กน้อย" จากคุณสมบัติของ MSHTMLinnerText (คัดลอกโดย Opera เช่นกันเมื่อเร็ว ๆ นี้ในบรรดาคุณสมบัติ MSHTML อื่น ๆ อีกมากมาย)
ก่อนอื่นการtextContentแทนช่องว่างจะแตกต่างจากที่innerTextหนึ่ง ที่สองและที่สำคัญกว่านั้นtextContent รวมเนื้อหาแท็ก SCRIPT ทั้งหมดโดยที่ InnerText ไม่ได้
เพียงเพื่อให้สิ่งต่าง ๆ สนุกสนานยิ่งขึ้น Opera - นอกเหนือจากการนำมาตรฐานไปใช้textContent- ตัดสินใจเพิ่ม MSHTML's innerText แต่เปลี่ยนให้ทำหน้าที่textContent - เช่นรวมถึงเนื้อหา SCRIPT (ในความเป็นจริงtextContentและinnerTextใน Opera ดูเหมือนจะให้ผลลัพธ์ที่เหมือนกัน .
textContentเป็นส่วนหนึ่งของNodeอินเตอร์เฟซในขณะที่เป็นส่วนหนึ่งของinnerText HTMLElementตัวอย่างเช่นสิ่งนี้หมายความว่าคุณสามารถ "ดึงข้อมูล" textContentแต่ไม่ได้innerTextมาจากโหนดข้อความ:
var el = document.createElement('p');
var textNode = document.createTextNode('x');
el.textContent; // ""
el.innerText; // ""
textNode.textContent; // "x"
textNode.innerText; // undefined
ในที่สุด Safari 2.x ก็มีinnerTextการติดตั้งบั๊กกี้ด้วย ใน Safari innerTextทำงานอย่างถูกต้องเฉพาะเมื่อองค์ประกอบนั้นไม่ถูกซ่อน (ผ่านstyle.display == "none") หรือเด็กกำพร้าจากเอกสาร มิฉะนั้นให้innerTextผลลัพธ์เป็นสตริงว่าง
ฉันกำลังเล่นกับtextContentนามธรรม (เพื่อแก้ไขข้อบกพร่องเหล่านี้) แต่มันกลับกลายเป็นว่าค่อนข้างซับซ้อนค่อนข้างซับซ้อน
ทางออกที่ดีที่สุดคือการกำหนดข้อกำหนดที่แน่นอนของคุณก่อนและปฏิบัติตามจากที่นั่น มักจะเป็นไปได้ที่จะดึงแท็กออกจากinnerHTMLองค์ประกอบแทนที่จะจัดการกับสิ่งที่เป็นไปได้ทั้งหมดtextContent/innerTextเบี่ยงเบนทั้งหมด
ความเป็นไปได้อีกประการหนึ่งคือการเดินทรี DOM และรวบรวมโหนดข้อความแบบเรียกซ้ำ
innerTextใน Chrome jsperf.com/text-content/3
textContentได้รับการสนับสนุนใน IE9 + แต่ Firefox ยังไม่รองรับinnerText(แม้ว่าพวกเขาจะเพิ่มการแนะนำ IE outerHTMLเมื่อไม่กี่วันที่ผ่านมา)
Node.textContentความคืบหน้าอย่างสมบูรณ์อยู่ที่นี่: github.com/usmonster/aight/blob/node-textcontent-shim/js/… (หวังว่าจะเร็ว ๆ นี้จะรวมอยู่ในaight )
หากคุณต้องการตั้งค่าเนื้อหาข้อความและไม่สามารถดึงข้อมูลได้นี่เป็นเวอร์ชั่น DOM เล็กน้อยที่คุณสามารถใช้กับเบราว์เซอร์ใดก็ได้ ไม่จำเป็นต้องใช้ส่วนขยาย IE innerText หรือคุณสมบัติ textContent Core ระดับ DOM 3
function setTextContent(element, text) {
while (element.firstChild!==null)
element.removeChild(element.firstChild); // remove all existing content
element.appendChild(document.createTextNode(text));
}
!== ===เปรียบเทียบประเภทที่มีความอ่อนไหวที่ใช้โดย===/ !==มักจะเป็นที่นิยมในการ comparators หลวม/== !=
!==nullอย่างสมบูรณ์โดยวิธีการ) แทนเพียงการเปลี่ยนวงด้วยelement.innerHTML=''(ซึ่ง specced จะทำผลงานเดียวกันแน่นอนเป็นห่วงและจากนั้นผมจำได้ .. .: tables in (legacy-) IE ... ericvasilik.com/2006/07/code-karma.html ฉันขอแนะนำให้เพิ่มคำอธิบายสั้น ๆ เกี่ยวกับ 'ซ่อน' และแทบไม่เคยบันทึกเอกสาร 'ผลข้างเคียง' ของการcreateTextNodeเปลี่ยนแอมป์ lt และ gt ไปยังเอนทิตีของ html ที่เกี่ยวข้องลิงก์ไปยังพฤติกรรมที่แน่นอนนั้นน่าจะยิ่งใหญ่!
ตามคำตอบของ Prakash K Firefox ไม่รองรับคุณสมบัติ InnerText ดังนั้นคุณสามารถทดสอบว่าตัวแทนผู้ใช้สนับสนุนคุณสมบัตินี้และดำเนินการตามด้านล่าง:
function changeText(elem, changeVal) {
if (typeof elem.textContent !== "undefined") {
elem.textContent = changeVal;
} else {
elem.innerText = changeVal;
}
}
Javascript บรรทัดที่ง่ายมากสามารถรับข้อความ "ไม่ติดแท็ก" ในเบราว์เซอร์หลักทั้งหมด ...
var myElement = document.getElementById('anyElementId');
var myText = (myElement.innerText || myElement.textContent);
textContentและinnerTextรายงานช่องว่างที่อาจมีความสำคัญสำหรับการใช้งานบางกรณี
||อย่างคือ: var myText = (myElement.innerText || myElement.textContent || "") ;เพื่อเอาชนะค่าที่ไม่ได้กำหนด
โปรดทราบว่าElement::innerTextคุณสมบัตินี้จะไม่มีข้อความที่ถูกซ่อนโดยสไตล์ CSS "display:none " ใน Google Chrome (รวมถึงจะวางเนื้อหาที่ถูกหลอกลวงโดยเทคนิค CSS อื่น ๆ (รวมถึงขนาดตัวอักษร: 0, สี: โปร่งใสและ เอฟเฟกต์อื่น ๆ ที่คล้ายกันซึ่งทำให้ข้อความไม่สามารถแสดงผลในลักษณะที่มองเห็นได้)
คุณสมบัติ CSS อื่น ๆ ยังได้รับการพิจารณา:
<br \>ที่สร้างขึ้นบรรทัดใหม่จะสร้างบรรทัดใหม่ในค่า innerTextแต่Element::textContentจะยังคงมีเนื้อหาทั้งหมดขององค์ประกอบข้อความด้านในอย่างอิสระของ CSS ที่ใช้แม้ว่าจะมองไม่เห็นก็ตาม และจะไม่มีการสร้างบรรทัดใหม่หรือช่องว่างพิเศษใน textContent ซึ่งเพียงละเว้นสไตล์ทั้งหมดและโครงสร้างและอินไลน์ / บล็อกหรือประเภทตำแหน่งขององค์ประกอบภายใน
สำเนา / วางการดำเนินงานโดยใช้ตัวเลือกเมาส์จะทิ้งข้อความที่ซ่อนอยู่ในรูปแบบข้อความธรรมดาที่จะใส่ในคลิปบอร์ดดังนั้นมันจะไม่ได้มีทุกอย่างในtextContentแต่เพียงสิ่งที่อยู่ภายในinnerText(หลังจากช่องว่าง / รุ่นขึ้นบรรทัดใหม่ข้างต้น) .
คุณสมบัติทั้งสองนี้ได้รับการสนับสนุนใน Google Chrome แต่เนื้อหาอาจมีความแตกต่างกัน เบราว์เซอร์รุ่นเก่ายังคงรวมอยู่ใน innetText ทุกอย่างเหมือนกับ textContent ในขณะนี้ (แต่พฤติกรรมของพวกเขาสัมพันธ์กับการสร้างช่องว่าง / การขึ้นบรรทัดใหม่ในตอนนั้นไม่สอดคล้องกัน)
jQuery จะแก้ปัญหาความไม่สอดคล้องกันเหล่านี้ระหว่างเบราว์เซอร์โดยใช้วิธี ".text ()" ที่เพิ่มเข้าไปในองค์ประกอบที่แยกวิเคราะห์ซึ่งจะส่งคืนผ่านการสืบค้น $ () ภายในจะแก้ปัญหาโดยการดูใน DOM HTML ทำงานเฉพาะกับระดับ "โหนด" ดังนั้นมันจะส่งคืนบางสิ่งที่ดูเหมือนข้อความมาตรฐานมากกว่า
ข้อแม้คือว่าวิธีการ jQuery นี้จะไม่แทรกช่องว่างเพิ่มเติมหรือตัวแบ่งบรรทัดที่อาจปรากฏบนหน้าจอที่เกิดจากองค์ประกอบย่อย (เช่น<br />) ของเนื้อหา
หากคุณออกแบบสคริปต์สำหรับการช่วยสำหรับการเข้าถึงและสไตล์ชีทของคุณได้รับการวิเคราะห์สำหรับการเรนเดอร์แบบไม่เกี่ยวกับหูเช่นปลั๊กอินที่ใช้ในการสื่อสารกับเครื่องอ่านอักษรเบรลล์เครื่องมือนี้ควรใช้ textContent หากต้องมีเครื่องหมายวรรคตอนเฉพาะ "display: none" และโดยทั่วไปจะรวมอยู่ในหน้าเว็บ (ตัวอย่างเช่นตัวยก / ตัวห้อย) มิฉะนั้น innerText จะสับสนมากในเครื่องอ่านอักษรเบรลล์
โดยทั่วไปแล้วข้อความที่ถูกซ่อนโดย CSS จะถูกละเว้นโดยเสิร์ชเอนจิ้นหลัก (ซึ่งจะแยก CSS ของหน้า HTML ของคุณและจะไม่สนใจข้อความที่ไม่ตัดกันสีบนพื้นหลัง) โดยใช้ตัวแยกวิเคราะห์ HTML / CSS และคุณสมบัติ DOM "innerText" เหมือนกับในเบราว์เซอร์ภาพที่ทันสมัย (อย่างน้อยเนื้อหาที่มองไม่เห็นนี้จะไม่ถูกจัดทำดัชนีดังนั้นข้อความที่ซ่อนไม่สามารถใช้เป็นเคล็ดลับในการบังคับให้รวมคำหลักบางคำในหน้าเพื่อตรวจสอบเนื้อหา); แต่ข้อความที่ซ่อนอยู่นี้จะปรากฏในหน้าผลลัพธ์ (หากหน้านั้นยังคงมีคุณสมบัติจากดัชนีที่จะรวมอยู่ในผลลัพธ์) โดยใช้คุณสมบัติ "textContent" แทน HTML เต็มเพื่อตัดสไตล์และสคริปต์เพิ่มเติม
หากคุณกำหนดข้อความธรรมดาบางอย่างในหนึ่งในสองคุณสมบัตินี้จะเขียนทับมาร์กอัปภายในและสไตล์ที่ใช้กับมัน (เฉพาะองค์ประกอบที่กำหนดจะเก็บประเภทคุณลักษณะและสไตล์) ดังนั้นคุณสมบัติทั้งสองจะมีเนื้อหาเดียวกัน . อย่างไรก็ตามตอนนี้เบราว์เซอร์บางตัวจะไม่เคารพการเขียนไปยัง innerText อีกต่อไปและจะให้คุณเขียนทับคุณสมบัติ textContent (คุณไม่สามารถแทรกมาร์กอัพ HTML เมื่อเขียนไปยังคุณสมบัติเหล่านี้เนื่องจากอักขระพิเศษ HTML จะถูกเข้ารหัสอย่างเหมาะสมโดยใช้การอ้างอิงอักขระตัวเลข ถ้าคุณแล้วอ่านinnerHTMLคุณสมบัติหลังจากที่ได้รับมอบหมายของหรือinnerTexttextContent
innerTextChrome ในการทดสอบของฉันจะไม่สนใจเฉพาะ "จอแสดงผล: ไม่มี" และ "การมองเห็น: ซ่อนอยู่"
myElement.innerText = myElement.textContent = "foo";
แก้ไข (ขอบคุณมาร์ค Amery สำหรับความคิดเห็นด้านล่าง): เฉพาะทำมันด้วยวิธีนี้ถ้าคุณรู้ว่าข้อกังขาว่ารหัสจะไม่มีการอาศัยการตรวจสอบการดำรงอยู่ของคุณสมบัติเหล่านี้เช่น (ตัวอย่าง) jQueryไม่ แต่ถ้าคุณใช้ jQuery คุณอาจใช้ฟังก์ชัน "text" และทำ $ ('# myElement'). text ('foo') ตามคำตอบอื่น ๆ
innerTextหรือtextContentเพื่อตัดสินใจว่าควรใช้อันไหน เมื่อตั้งค่าทั้งสองเป็นสตริงคุณจะทำให้โค้ดของคนอื่นทำหน้าที่ในองค์ประกอบที่ตรวจพบโดยผิดพลาดว่าเบราว์เซอร์รองรับคุณสมบัติทั้งสอง ดังนั้นรหัสนั้นมีแนวโน้มที่จะทำงานผิดปกติ
innerTextถูกเพิ่มใน Firefox และควรมีอยู่ในรุ่น FF45: https://bugzilla.mozilla.org/show_bug.cgi?id=264412
ร่างข้อกำหนดได้ถูกเขียนขึ้นและคาดว่าจะรวมอยู่ในมาตรฐานการใช้ชีวิต HTML ในอนาคต: http://rocallahan.github.io/innerText-spec/ , https://github.com/whatwg/html/issues/ 465
โปรดทราบว่าในปัจจุบันการใช้งาน Firefox, Chrome และ IE ทั้งหมดเข้ากันไม่ได้ ก้าวไปข้างหน้าเราอาจคาดหวังว่า Firefox, Chrome และ Edge จะมาบรรจบกันในขณะที่ IE เก่ายังคงเข้ากันไม่ได้
ดูเพิ่มเติมที่: https://github.com/whatwg/compat/issues/5
innerTextในการดำเนินการใช้เพียง ถ้าtextContentเป็นทางเลือกที่ยอมรับได้และคุณต้องการที่จะสนับสนุน Fx (innerText || textContent)เก่าแล้วใช้ หากคุณต้องการการใช้งานที่เหมือนกันในทุกเบราว์เซอร์ฉันไม่เชื่อว่ามีโพลีฟิลเฉพาะสำหรับเรื่องนี้ แต่บางเฟรมเวิร์ก (เช่น jQuery) อาจใช้สิ่งที่คล้ายกันอยู่แล้ว - อ้างถึงคำตอบอื่น ๆ ในหน้านี้
innerTextนั่นคือ: ข้อความที่มองเห็นได้บนหน้าเว็บใน Firefox> = 38 (สำหรับแอดออน) อย่างน้อยที่สุด<script>แท็กควรถูกตัดออกอย่างสมบูรณ์ jQuery $('#body').text()ไม่ได้ผลสำหรับฉัน แต่เป็นวิธีแก้ปัญหาinnerText || textContentก็โอเค ขอบคุณ.
textContentในตอนนี้
แล้วเรื่องแบบนี้ล่ะ?
//$elem is the jQuery object passed along.
var $currentText = $elem.context.firstChild.data.toUpperCase();
** ฉันต้องการสร้างตัวพิมพ์ใหญ่ของฉัน
เช่นเดียวกับในปี 2559 จาก Firefox v45 innerTextทำงานบน firefox ลองดูการสนับสนุน: http://caniuse.com/#search=innerText
หากคุณต้องการให้มันทำงานบน Firefox เวอร์ชันก่อนหน้าคุณสามารถใช้textContentซึ่งมีการรองรับ Firefox ที่ดีขึ้น แต่แย่กว่า IE เวอร์ชันเก่ากว่า : http://caniuse.com/#search=textContent
นี้ได้รับประสบการณ์ของฉันกับinnerText, textContent, innerHTMLและความคุ้มค่า:
// elem.innerText = changeVal; // works on ie but not on ff or ch
// elem.setAttribute("innerText", changeVal); // works on ie but not ff or ch
// elem.textContent = changeVal; // works on ie but not ff or ch
// elem.setAttribute("textContent", changeVal); // does not work on ie ff or ch
// elem.innerHTML = changeVal; // ie causes error - doesn't work in ff or ch
// elem.setAttribute("innerHTML", changeVal); //ie causes error doesn't work in ff or ch
elem.value = changeVal; // works in ie and ff -- see note 2 on ch
// elem.setAttribute("value", changeVal); // ie works; see note 1 on ff and note 2 on ch
ie = internet explorer, ff = firefox, ch = google chrome หมายเหตุ 1: ff ทำงานจนกระทั่งหลังจากลบค่าด้วย backspace - ดูหมายเหตุโดย Ray Vega ด้านบน หมายเหตุ 2: ใช้งานได้ในโครเมี่ยม - หลังจากอัปเดตแล้วจะไม่มีการเปลี่ยนแปลงจากนั้นคุณคลิกออกไปแล้วคลิกกลับไปที่ฟิลด์และค่าจะปรากฏขึ้น ที่ดีที่สุดของจำนวนมากคือelem.value = changeVal; ซึ่งฉันไม่ได้แสดงความคิดเห็นข้างต้น
เพียงโพสต์ใหม่จากความคิดเห็นใต้โพสต์ต้นฉบับ innerHTML ทำงานได้กับเบราว์เซอร์ทั้งหมด ขอบคุณ stefita
myElement.innerHTML = "foo";
innerHTMLไม่ใช่การแทนที่อย่างเพียงพอสำหรับtextContent/ innerTextเว้นแต่คุณจะมั่นใจได้ว่าข้อความที่คุณกำหนดไม่มีแท็กหรือไวยากรณ์ HTML อื่น ๆ สำหรับข้อมูลใด ๆ ที่ได้รับจากผู้ใช้คุณไม่มีการรับประกันแน่นอน การกดวิธีนี้โดยไม่มีข้อแม้นั้นเป็นสิ่งอันตรายเพราะมันสามารถนำไปสู่ช่องโหว่ความปลอดภัยของXSS ด้วยวิธีการที่ปลอดภัยมากมายที่มีอยู่ไม่มีเหตุผลที่จะต้องพิจารณาวิธีนี้
.innerHTMLรหัสของคุณจะเสียหายและคุณอาจเสี่ยงต่อ XSS จะเกิดอะไรขึ้นถ้าสตริงนั้นคือ"<script>alert(1)</script>"อะไร?
<script>แท็กที่แทรกผ่านinnerHTMLไม่ควรดำเนินการ แต่นั่นไม่ได้ป้องกันเบราว์เซอร์รุ่นเก่า นอกจากนี้ HTML5 innerHTMLจะไม่ปกป้องเช่น"<img src='x' onerror='alert(1)'>"กัน
พบที่นี่:
<!--[if lte IE 8]>
<script type="text/javascript">
if (Object.defineProperty && Object.getOwnPropertyDescriptor &&
!Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get)
(function() {
var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
Object.defineProperty(Element.prototype, "textContent",
{ // It won't work if you just drop in innerText.get
// and innerText.set or the whole descriptor.
get : function() {
return innerText.get.call(this)
},
set : function(x) {
return innerText.set.call(this, x)
}
}
);
})();
</script>
<![endif]-->
textContentโดยกำเนิด ? นอกจากนี้ยังเป็นที่น่าสังเกตว่าตั้งแต่innerTextและtextContentมีพฤติกรรมที่แตกต่างกันรหัสข้างต้นไม่ใช่textContentshim ที่ซื่อสัตย์- นี่อาจเป็นสิ่งสำคัญ แต่ไม่จำเป็นต้องชัดเจน!
เป็นไปได้ที่จะเลียนแบบinnerTextพฤติกรรมในเบราว์เซอร์อื่น:
if (((typeof window.HTMLElement) !== "undefined") && ((typeof HTMLElement.prototype.__defineGetter__) !== "undefined")) {
HTMLElement.prototype.__defineGetter__("innerText", function () {
if (this.textContent) {
return this.textContent;
} else {
var r = this.ownerDocument.createRange();
r.selectNodeContents(this);
return r.toString();
}
});
HTMLElement.prototype.__defineSetter__("innerText", function (str) {
if (this.textContent) {
this.textContent = str;
} else {
this.innerHTML = str.replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/\n/g, "<br />\n");
}
});
}
preเพราะมันจะขึ้นบรรทัดใหม่เป็นสองเท่า ฉันสงสัยว่ามีอะไรผิดปกติมากขึ้นที่นี่