'innerText' IE'de çalışır, ancak Firefox'ta çalışmaz


289

Aşağıdakileri içeren IE çalışan bazı JavaScript kodu var:

myElement.innerText = "foo";

Ancak, 'innerText' özelliği Firefox'ta çalışmıyor gibi görünüyor. Bazı Firefox eşdeğeri var mı? Yoksa kullanılabilecek daha genel, çapraz tarayıcı özelliği var mı?


3
Bunu yapmalı myElement.innerHTML = "foo";
stefita

Bu, nesnenin içindeki TÜM HTML'yi sağlanan değerle değiştirir.
OMG Ponies

24
Bu, jQuery gibi kitaplıkların, standart bir çerçeve kullanmanızı sağlayarak bunun gibi tarayıcılar arası tutarsızlıklarla ilgilenmelerini sağlayarak hayatı kolaylaştırır.
Dan Diplo

Ancak, ilgilenilecek HTML yoksa yine de uygun olabilir.
Alex Polo

21
Bu nedenle, bunun mümkün olduğunu (yapıcı olmayan) söylemek yerine bu çapraz tarayıcı alternatifini nasıl kullanacağımızı bize bildirin.
SasQ

Yanıtlar:


249

Firefox, W3C uyumlu textContent özelliğini kullanır .

Safari ve Opera'nın da bu özelliği desteklediğini tahmin ediyorum.



2
@Bob 22 Şub 2016 itibarıyla hala değil.
krillgar

@krillgar 8 Mart haftasında çıkması planlanan Firefox 45 için planlandı. Zaten mevcut beta sürümünde ve bir süredir aurora'da. Bu pratikte ne anlama geliyor, innerTextsadece kullanarak siteleri geliştirmeye başlayabilir ve yakın gelecekte tüm mevcut tarayıcılarda ve (eski IE) de (olası tuhaflıklar ile) çalışmasını bekleyebilirsiniz.
Bob

1
FTR: innerTextolup derinden farklı gelen textContentve aslında (bir farz IE cilvesi ... dan şaşırtıcı) çok yararlıdır: innerTextçalışır metin nasıl bir yaklaşım vermek aslında sunulan tamamen farklı olarak tarayıcıda textContent, hangi hemen döner etiketi- işaretleme kaynağını kaldırmış , çok az değer katmış , hatta ekstra problemler (kelime sınırlarının kaybı gibi).
Sz.

innerText, 64 sürümünde 2019'da hala desteklenmiyor.
Tony Dong

285

Güncelleme : Tüm farkları daha iyi detaylandıran bir blog yazısı yazdım .


Firefox W3C standardını kullanır Node::textContent, ancak davranışı MSHTML'nin tescilli olanından "biraz" farklıdır innerText(onlarca diğer MSHTML özelliği arasında Opera tarafından da bir süre önce kopyalanmıştır).

Her şeyden önce, textContentbeyaz alan gösterimi innerTextbirinden farklıdır . İkincisi ve daha da önemlisi, textContent tüm SCRIPT etiketi içeriklerini içerirken, innerText içermez.

Sadece işleri daha eğlenceli hale getirmek için, Opera - standardı uygulamanın yanı sıra textContent- MSHTML'leri de eklemeye karar verdi, innerText ancak bunu değiştirecek şekilde değiştirditextContent - yani SCRIPT içerikleri dahil (aslında textContentve innerTextOpera'da muhtemelen birbirleriyle aynı şekilde taklit edilen) aynı sonuçlar üretiyor gibi görünüyor .

textContentNodearayüzün bir parçası , oysa innerTextbir parçasıdır HTMLElement. Bu, örneğin, araç siz "almak" anlamına textContentdeğil, innerTextmetin düğümlerden:

var el = document.createElement('p');
var textNode = document.createTextNode('x');

el.textContent; // ""
el.innerText; // ""

textNode.textContent; // "x"
textNode.innerText; // undefined

Son olarak, Safari 2.x'in de hatalı bir innerTextuygulaması var. Safari'de, innerTextyalnızca bir öğe style.display == "none"belgeden gizlenmediği ( veya geçmediği) veya öksüz kaldığında düzgün çalışır . Aksi takdirde, innerTextboş bir dizeyle sonuçlanır.

textContentSoyutlama ile oynuyordum (bu eksikliklerin üstesinden gelmek için), ama oldukça karmaşık olduğu ortaya çıktı .

Yapmanız gereken en iyi şey, önce tam gereksinimlerinizi tanımlamak ve oradan takip etmektir . Etiketleri innerHTML, olası tüm textContent/ innerTextsapmalarla uğraşmak yerine bir öğeden çıkarmak genellikle mümkündür .

Başka bir olasılık, elbette, DOM ağacını yürümek ve tekrarlanan metin düğümlerini toplamaktır.


35
Chrome innerText'i de destekler, bu yüzden Firefox desteklemeyen tek büyük tarayıcı gibi görünüyor. IE, textContent'i desteklemeyen tek tarayıcıdır.
mike nelson

7
@mike - Ancak innerText, Chrome'da kullanımı 60 kat daha yavaş görünüyor . jsperf.com/text-content/3
gblazex

8
textContentşu anda IE9 + 'da desteklenmektedir, ancak Firefox hala desteklememektedir innerText( outerHTMLbirkaç gün önce IE ile tanıtılan eklediler).
kanguru

1
Hala IE8 desteklemek için ihtiyaç duyanlar için, oldukça komple var Node.textContent: Burada devam eden pul github.com/usmonster/aight/blob/node-textcontent-shim/js/... (Umarım yakında eklenecek aight ).
Noyo


83

Yalnızca metin içeriğini ayarlamanız ve almamanız gerekiyorsa, işte herhangi bir tarayıcıda kullanabileceğiniz önemsiz bir DOM sürümü; IE innerText uzantısını veya DOM Level 3 Core textContent özelliğini gerektirmez.

function setTextContent(element, text) {
    while (element.firstChild!==null)
        element.removeChild(element.firstChild); // remove all existing content
    element.appendChild(document.createTextNode(text));
}

JavaScript'in "! ==" operatörü olmadığı sürece, ikinci satırdaki operatörün sadece "! =" Olması gerektiğini düşünüyorum.
RexE

23
@RexE: JavaScript'in !==tersi bir işleç var ===. ===/ Tarafından kullanılan türe duyarlı karşılaştırma !==genellikle gevşek karşılaştırıcılara ==/ tercih edilir !=.
bobince

Internet explorer bu komut dosyası etiketlerinin metnini ayarlamak için çalışmaz (bir şablon için kullanıyordum). `ScriptTagElement.text = 'şablonum {{here}}' ayarladınız;
Christopher Tarquini

Ben sadece döngü yerine (hangi döngü ile aynı işi yapmak için belirtilen ve sonra hatırladım ) yerine döngü (ve bu arada tamamen atmak istiyorsunuz) anlamak için çok zor düşünmek zorunda kaldı .. .: (legacy-) IE ... tablolar ericvasilik.com/2006/07/code-karma.html ben 'gizli' ve hemen hemen kısa bir açıklama eklemenizi öneririz olabilir asla belgelenmiş 'yan etkisi' yerine amfi lt ve gt onların ilgili html karakter varlıklarına? Kesin davranışına bir bağlantı büyük olurdu!!==nullelement.innerHTML=''createTextNode
GitaarLAB


22

Prakash K'nin cevabına göre Firefox innerText özelliğini desteklemiyor. Böylece, kullanıcı aracısının bu özelliği destekleyip desteklemediğini test edebilir ve aşağıdaki gibi devam edebilirsiniz:

function changeText(elem, changeVal) {
    if (typeof elem.textContent !== "undefined") {
        elem.textContent = changeVal;
    } else {
        elem.innerText = changeVal;
    }
}

2
elem'deki 'textContent' daha basit olurdu
Jamie Pate

if (elem.textContent! = null) da daha kolay olurdu!
Elmue

14

Gerçekten basit bir Javascript satırı, tüm ana tarayıcılarda "taggy olmayan" metni alabilir ...

var myElement = document.getElementById('anyElementId');
var myText = (myElement.innerText || myElement.textContent);

2
Bununla ilgili bir sorun var (en azından IE8'de): innerText boş bir dize ve textContent tanımsızsa (myElement.innerText || myElement.textContent) tanımsız hale gelir.
Magnus

1
@Magnus tarafından not edilen hatanın yanı sıra, bazı kullanım durumları için önemli olabilecek boşlukların nasıl rapor edileceği textContentve innerTextraporlanacağı konusunda önemli farklar olduğu gerçeğinin de farkında olmak önemlidir .
Mark Amery

2
Bunun için başka bir ekleme ||yani: var myText = (myElement.innerText || myElement.textContent || "") ;tanımsız değerini aşmak için.
PeterM

6

O Not Element::innerTextözelliği olacak değil CSS stili "tarafından gizlendi metin içeren display:none0, renk: şeffaf, ve de buna (font-size dahil diğer CSS teknikleri ile maskelenmiş olan içerikleri düşecek şekilde (Google Chrome'da" metnin görünür bir şekilde görüntülenmemesine neden olan birkaç benzer efekt).

Diğer CSS özellikleri de dikkate alınır:

  • İlk olarak, iç öğelerin "display:" stili, tarayıcının yerleşik stil sayfasındaki HTML blok öğelerinin varsayılanı olan ve davranışını geçersiz kılmayan bir blok içeriğini ("display: block" gibi) sınırlayıp sınırlamadığını belirlemek için ayrıştırılır. kendi CSS stiliniz); eğer öyleyse innerText özelliğinin değerine bir yeni satır eklenir. Bu textContent özelliğinde gerçekleşmez.
  • Satır içi içerikler üreten CSS özellikleri de dikkate alınacaktır: örneğin satır <br \>içi bir satırsonu oluşturan satır içi eleman , innerText değerinde bir satırsonu oluşturur.
  • "Display: satır içi" stili, textContent veya innerText öğelerinde yeni satıra neden olmaz.
  • "Display: table" stili, tablonun etrafında ve tablo satırları arasında yeni satırlar oluşturur, ancak "display: table-cell" bir tablolama karakteri oluşturur.
  • "Position: absolute" özelliği (display: block veya display: inline ile birlikte kullanılır, önemli değil) de satır kesmesinin eklenmesine neden olur.
  • Bazı tarayıcılarda açıklıklar arasında tek bir boşluk ayrılması da bulunur

Ancak Element::textContentyine de, görünmez olsalar bile, uygulanan CSS'den bağımsız olarak iç metin öğelerinin TÜM içeriğini içerir. Ve textContent'te fazladan yeni satırlar veya boşluklar oluşturulmaz; bu, tüm stilleri ve yapıyı ve satır içi / blok veya konumlandırılmış iç eleman türlerini göz ardı eder.

Fare seçimini kullanarak bir kopyala / yapıştır işlemi, gizli metni panoya yerleştirilen düz metin biçiminde atar, bu nedenle içindeki her şeyi içermez textContent, ancak yalnızca içinde olanı içerir innerText(beyaz boşluk / yeni satır oluşturulduktan sonra yukarıdaki gibi) .

Daha sonra her iki mülk de Google Chrome'da desteklenir, ancak içerikleri farklı olabilir. Daha eski tarayıcılar hala textContent'in içerdiği gibi innetText'te her şeye dahil edildi (ancak o zamanlar beyaz alanların / yeni satırların oluşturulmasıyla ilgili davranışları tutarsızdı).

jQuery, tarayıcılar arasındaki bu tutarsızlıkları, $ () sorgusu aracılığıyla döndürdüğü ayrıştırılmış öğelere eklenen ".text ()" yöntemini kullanarak çözecektir. Dahili olarak, yalnızca "düğüm" düzeyinde çalışarak HTML DOM'ye bakarak zorlukları çözer. Böylece daha çok standart textContent gibi görünen bir şey döndürür.

Uyarı, bu jQuery yönteminin <br />, içeriğin alt öğelerinin (gibi ) neden olduğu ekranda görülebilecek fazladan boşluklar veya satır kesmeleri eklememesidir .

Erişilebilirlik için bazı komut dosyaları tasarlarsanız ve stil sayfanız, Braille okuyucuyla iletişim kurmak için kullanılan eklentiler gibi işitmeyen oluşturma için ayrıştırılırsa, bu araç, stilize olan açıklıklara eklenen belirli noktalama işaretlerini içermesi gerekiyorsa textContent'i kullanmalıdır. "display: none" ve genellikle sayfalara dahil edilir (örneğin üst yazılar / abonelikler için), aksi takdirde innerText Braille okuyucusunda çok kafa karıştırıcı olacaktır.

CSS hileleriyle gizlenen metinler artık bir HTML / CSS ayrıştırıcısı ve DOM özelliği kullanılarak büyük arama motorları tarafından (genellikle HTML sayfalarınızın CSS'sini ayrıştıracak ve arka plan üzerinde kontrast renkte olmayan metinleri de yok sayar) yok sayılır. "innerText" tıpkı modern görsel tarayıcılarda olduğu gibi (en azından bu görünmez içerik dizine eklenmeyecektir, bu nedenle gizli metin, içeriğinin kontrol edilmesi için bazı anahtar kelimelerin sayfaya eklenmesini zorlamak için bir hile olarak kullanılamaz); ancak bu gizli metin, sonuç sayfalarında (sayfa sonuçlara eklenecek dizinden hala kalifiye olmuşsa), ek stilleri ve komut dosyalarını şeritlemek için tam HTML yerine "textContent" özelliğini kullanarak görüntülenecektir.

Bu iki özellikten herhangi birine düz metin atarsanız, bu, kendisine uygulanan iç işaretlemenin ve stillerin üzerine yazar (yalnızca atanan öğe türünü, niteliklerini ve stillerini korur), böylece her iki özellik de aynı içeriği içerir . Bununla birlikte, bazı tarayıcılar artık innerText'e yazmayı onurlandırmayacak ve yalnızca textContent özelliğinin üzerine yazmanıza izin verecek (bu özelliklere yazarken HTML işaretlemesi ekleyemezsiniz, çünkü HTML özel karakterleri tam anlamıyla görünmek için sayısal karakter referansları kullanılarak düzgün bir şekilde kodlanır , veya innerHTMLöğesinin atanmasından sonra özelliği okuduysanız .innerTexttextContent


1
Aslında "yazı tipi boyutu: 0", "renk: saydam", "opaklık: 0", "metin girintisi: -9999px" vb. Chrome / WebKit'in içine dahil edilmiştir innerText. Testlerimde yalnızca "display: none" ve "visibility: hidden" yok sayılır.
kanguru

5
myElement.innerText = myElement.textContent = "foo";

Düzenleme (Mark Amery'ye aşağıdaki yorum için teşekkürler): Bunu, yalnızca (örneğin) jQuery gibi, bu özelliklerin varlığını kontrol etmeye hiçbir kodun güvenmeyeceğinin makul bir şüphe ötesinde biliyorsanız, bu şekilde yapın . Ancak jQuery kullanıyorsanız, muhtemelen "text" işlevini kullanırsınız ve diğer bazı yanıtların gösterdiği gibi $ ('# myElement'). Text ('foo') yaparsınız.


4
1; bu kötü bir fikir. Kodun ( jQuery gibi kitaplıklardaki kod dahil) hangisinin kullanılacağına karar vermek için innerTextveya textContentözelliklerinin varlığını kontrol etmesi son derece yaygındır . Her ikisini de bir dizeye ayarlayarak, diğer kişilerin öğeye etki eden kodunun, tarayıcının her iki özelliği de desteklediğini yanlışlıkla algılamasını sağlarsınız; sonuç olarak bu kod yanlış davranmakla yükümlüdür.
Mark Amery

JQuery $ ('# myElement'). Val () çapraz tarayıcı için çalışır.
Tony Dong

4

innerTextFirefox'a eklendi ve FF45 sürümünde mevcut olmalıdır: https://bugzilla.mozilla.org/show_bug.cgi?id=264412

Bir taslak şartname yazılmıştır ve gelecekte HTML yaşam standardına dahil edilmesi beklenmektedir: http://rocallahan.github.io/innerText-spec/ , https://github.com/whatwg/html/issues/ 465

Şu anda Firefox, Chrome ve IE uygulamalarının uyumsuz olduğunu unutmayın. İleride, eski IE uyumsuzken Firefox, Chrome ve Edge'in yakınsamalarını bekleyebiliriz.

Ayrıca bkz: https://github.com/whatwg/compat/issues/5


Kullanılabilir bir çoklu dolgu var mı?
serv-inc

1
@user Gerçekten neye ihtiyacınız olduğuna bağlı. Firefox'un eski sürümlerini desteklemeniz gerekmiyorsa ve uygulamadaki küçük farkları umursamıyorsanız, sadece kullanın innerText. Eğer textContentkabul edilebilir bir geri dönüş olduğunu ve eski Fx desteklemesi gerektiğini de sonra kullanmak (innerText || textContent). Tüm tarayıcılarda aynı bir uygulama istiyorsanız, bunun için belirli bir çoklu dolgu olduğuna inanmıyorum, ancak bazı çerçeveler (örn. JQuery) zaten benzer bir şey uygulayabilir - bu sayfadaki diğer cevaplara bakın.
Bob

1
İşlevselliği innerText, yani: sayfadaki görünür Metin, Firefox> = 38 (bir eklenti için) En azından, <script>etiketler tamamen atlanmalıdır. jQuery $('#body').text()benim için çalışmadı. Ama bir çözüm innerText || textContentolarak tamam. Teşekkür ederim.
serv-inc

@ kullanıcı Evet, Fx 38'i desteklemeniz gerekiyorsa bu cevap gerçekten geçerli değildir. textContentŞimdilik sınırlama / farklılıklarla yaşamak zorunda kalacaksınız .
Bob

1

Böyle bir şeye ne dersin?

//$elem is the jQuery object passed along.

var $currentText = $elem.context.firstChild.data.toUpperCase();

** Benimkini büyük yapmam gerekiyordu.


1
Bok çözeltisi; öğe tek bir metin düğümünden başka bir şey içeriyorsa bu çalışmaz.
Mark Amery


0

Bu benim deneyim oldu innerText, textContent, innerHTMLve değer:

// 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. not 1: ff, değer geri silme ile silinene kadar çalışır - yukarıdaki Ray Vega'nın notuna bakın. not 2: kromda biraz çalışır - güncellemeden sonra değişmeden sonra uzağa tıklayıp alana geri tıklarsınız ve değer görünür. Partinin en iyisi elem.value = changeVal; ki ben yukarıda yorum yapmadım.


1
sadece ben mi ? veya OP sorusunu abosolutly yoksay? innerText / textContent istedi ve siz çoğunlukla girdilerden bahsediyorsunuz.
Dementic

Bu cevabı okumak çok zor. Öte yandan, içeriğin toplanmaya değecek kadar değerli olduğuna ikna olmadım.
Mark Amery

-1

Sadece orijinal gönderinin altındaki yorumlardan yeniden gönderiyorum. innerHTML tüm tarayıcılarda çalışır. Teşekkürler stefita.

myElement.innerHTML = "foo";


1
1; atadığınız metnin herhangi bir etiket veya başka HTML sözdizimi içermediğinden emin olmadığınız sürece / innerHTMLiçin yeterli bir değişiklik değildir. Kullanıcı tarafından sağlanan herhangi bir veri için kesinlikle bu garantiniz yoktur. Bu yaklaşımı bu uyarı olmadan zorlamak, XSS güvenlik deliklerine yol açabileceği için tehlikelidir . Mevcut pek çok güvenli yaklaşımla, bunu düşünmek için bile bir neden yok. textContentinnerText
Mark Amery

Mark, anlayışım, innerHTML'nin div, span, p gibi html öğelerine veri yazmanın normal bir yolu olduğudur. Döndürülen JSON verilerini işlemek için kullanıyorum.
JQuery'de

1
JSON yanıtından rasgele bir dize alıp bir öğeye .innerHTMLatarsanız, kodunuz bozulur ve potansiyel olarak XSS'ye karşı savunmasızsınız demektir. Bu dize ise ne olur "<script>alert(1)</script>"?
Mark Amery

1
@MarkAmery: HTML5, <script>üzerinden eklenen bir etiketin innerHTMLyürütülmemesi gerektiğini belirtir . Ancak bu, eski tarayıcıları korumaz. Ayrıca, HTML5 innerHTML, örneğin koruma ETMEZ "<img src='x' onerror='alert(1)'>".
GitaarLAB

-1

burada buldum:

<!--[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]-->

Bazı açıklamalar iyi olurdu! Ayrıca, burada garip bir şeyler var; IE> = 9 yerel olarak desteklendiğindetextContent , yürütmeyi yalnızca IE 8'i hedeflemek yerine IE> = 8 ile sınırlamak için koşullu bir yorum neden kullanılır ? Ayrıca , farklı davranışlara sahip olduklarından innerTextve textContentyukarıdaki davranışların sadık bir textContentşim olmadığını da belirtmek gerekir - bu potansiyel olarak önemlidir, ancak mutlaka açık değildir!
Mark Amery

kusur işaret ettiğiniz için teşekkür ederim, IE olması amaçlanmıştır <= 8
simonarame

-2

innerTextDiğer tarayıcılardaki davranışları taklit etmek de mümkündür :

 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, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/\n/g, "<br />\n");
         }
     });
 }

Sadece başımın üstünden problemler arayan setter, presatırsonlarını ikiye katlayacağı için s için kırıldı . Burada daha fazla yanlış olduğundan şüpheleniyorum.
Mark Amery
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.