web-dev-qa-db-fra.com

'innerText' fonctionne dans IE, mais pas dans Firefox

J'ai du code JavaScript qui fonctionne dans IE et qui contient les éléments suivants:

myElement.innerText = "foo";

Cependant, il semble que la propriété 'innerText' ne fonctionne pas dans Firefox. Existe-t-il un équivalent de Firefox? Ou existe-t-il une propriété plus générique, multi-navigateurs, utilisable?

286
Ray Vega

Firefox utilise la propriété conforme au W3CtextContent .

Je suppose que Safari et Opera supportent également cette propriété.

247
Prakash K

Mise à jour: J'ai écrit un post de blog détaillant toutes les différences beaucoup mieux.


Firefox utilise la norme Node::textContent du W3C, mais son comportement diffère "légèrement" de celui de la propriété innerText propriétaire de MSHTML (copiée par Opera également il y a quelque temps parmi des dizaines d'autres fonctionnalités MSHTML ).

Tout d’abord, textContent la représentation des espaces est différente de celle de innerText. Deuxièmement, et plus important encore, textContent inclut tout le contenu des balises SCRIPT , contrairement à innerText.

Juste pour rendre les choses plus amusantes, Opera - en plus de mettre en œuvre le standard textContent - a décidé d'ajouter également le innerText de MSHTML, mais l'a modifié pour qu'il devienne textContent - c’est-à-dire que le contenu de SCRIPT est en fait (textContent et innerText dans Opera semble produire des résultats identiques, probablement aliasés les uns aux autres).

textContent fait partie de Node interface, alors que innerText fait partie de HTMLElement. Cela signifie, par exemple, que vous pouvez "récupérer" textContent mais pas innerText à partir de nœuds de texte:

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

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

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

Enfin, Safari 2.x a également une implémentation buggy innerText. Dans Safari, innerText ne fonctionne correctement que si un élément n'est ni caché (via style.display == "none") ni orphelin dans le document. Sinon, innerText donne une chaîne vide.

Je jouais avec textContent abstraction (pour résoudre ces problèmes), mais il s’est avéré que plutôt complexe .

La meilleure chose à faire est de d'abord définir vos exigences exactes et de suivre à partir de là. Il est souvent possible de simplement enlever les balises de innerHTML d'un élément, plutôt que de gérer toutes les déviations possibles textContent/innerText.

Une autre possibilité consiste bien entendu à parcourir l’arborescence DOM et à collecter les nœuds de texte de manière récursive.

278
kangax

Si vous avez seulement besoin de définir du contenu texte et de ne pas le récupérer, voici une version DOM simple que vous pouvez utiliser sur n’importe quel navigateur; il ne nécessite ni l'extension IE innerText ni la propriété textContent du DOM niveau 3.

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

jQuery fournit une méthode .text() qui peut être utilisée dans n'importe quel navigateur. Par exemple:

$('#myElement').text("Foo");
25
user161433

Selon la réponse de Prakash K, Firefox ne prend pas en charge la propriété innerText. Vous pouvez donc simplement tester si l'agent utilisateur prend en charge cette propriété et procéder en conséquence comme suit:

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

Une simple ligne de Javascript permet d’obtenir le texte "non taggy" dans tous les principaux navigateurs ...

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

Notez que la propriété Element::innerText contiendra pas le texte masqué par le style CSS "display:none" dans Google Chrome (il sera également supprimé le contenu masqué par d'autres techniques CSS (notamment font-size: 0, color: transparent et quelques autres effets similaires empêchant le rendu du texte de manière visible).

D'autres propriétés CSS sont également considérées:

  • Tout d'abord, le style "display:" des éléments internes est analysé pour déterminer s'il délimite un contenu de bloc (tel que "display: block", qui est la valeur par défaut des éléments de bloc HTML dans la feuille de style intégrée du navigateur, et dont le comportement n'a pas été annulé par votre propre style CSS); Si c'est le cas, une nouvelle ligne sera insérée dans la valeur de la propriété innerText. Cela n'arrivera pas avec la propriété textContent.
  • Les propriétés CSS qui génèrent des contenus inline seront également prises en compte: par exemple, l'élément inline <br \> qui génère une nouvelle ligne inline générera également une nouvelle ligne dans la valeur de innerText.
  • Le style "display: inline" ne provoque aucune nouvelle ligne dans textContent ou innerText.
  • Le style "display: table" génère des nouvelles lignes autour de la table et entre les lignes, mais "display: table-cell" génère un caractère de tabulation.
  • La propriété "position: absolute" (utilisée avec display: block ou display: inline, cela n'a pas d'importance) provoquera également l'insertion d'un saut de ligne.
  • Certains navigateurs incluent également une séparation d'espacement unique entre les étendues.

Mais Element::textContent contiendra toujours TOUS les contenus des éléments de texte internes indépendamment du CSS appliqué même s'ils sont invisibles. De plus, textContent ne générera pas de sauts de lignes ni d'espaces supplémentaires, ce qui ignore simplement tous les styles, la structure et les types d'éléments internes inline/block ou positionnés.

Une opération de copier/coller utilisant la sélection de la souris supprimera le texte masqué au format texte brut qui est placé dans le presse-papiers. Ainsi, il ne contiendra pas tout le contenu du textContent, mais uniquement le contenu de innerText (après la génération d'espaces/de nouvelles lignes). au dessus de).

Les deux propriétés sont alors prises en charge dans Google Chrome, mais leur contenu peut alors être différent. Les navigateurs plus anciens incluaient toujours dans innetText tout ce qui est contenu dans textContent (mais leur comportement vis-à-vis de la génération des espaces et des nouvelles lignes était alors inconsistant).

jQuery résoudra ces incohérences entre les navigateurs en utilisant la méthode ".text ()" ajoutée aux éléments analysés qu'il renvoie via une requête $ (). En interne, cela résout les difficultés en regardant dans le DOM HTML, en travaillant uniquement avec le niveau "nœud". Donc, il retournera quelque chose qui ressemble plus au textContent standard.

L'avertissement est que cette méthode jQuery n'insérera pas d'espaces ni de sauts de ligne supplémentaires pouvant être visibles à l'écran et causés par des sous-éléments (comme <br />) du contenu.

Si vous concevez des scripts pour l'accessibilité et que votre feuille de style est analysée pour un rendu non auditif, tels que les plug-ins utilisés pour communiquer avec un lecteur braille, cet outil doit utiliser textContent s'il doit inclure les signes de ponctuation spécifiques ajoutés à des étendues stylisées avec "display: none" et qui sont généralement inclus dans les pages (par exemple pour les exposants/indices), sinon le innerText sera très déroutant sur le lecteur braille.

Les textes cachés par les astuces CSS sont maintenant généralement ignorés par les principaux moteurs de recherche (qui analyseront également le CSS de vos pages HTML et ignoreront également les textes ne présentant pas de couleurs contrastées à l'arrière-plan) à l'aide d'un analyseur HTML/CSS et de la propriété DOM "innerText" exactement comme dans les navigateurs visuels modernes (au moins ce contenu invisible ne sera pas indexé, le texte masqué ne peut donc pas être utilisé comme une astuce pour forcer l'inclusion de certains mots-clés dans la page afin de vérifier son contenu); mais ce texte masqué sera toujours affiché dans la page de résultat (si la page était encore qualifiée de l'index pour être incluse dans les résultats), en utilisant la propriété "textContent" au lieu du code HTML complet pour supprimer les styles et scripts supplémentaires.

Si vous affectez du texte brut dans l’une de ces deux propriétés, cela écrasera le balisage interne et les styles qui lui sont appliqués (seul l’élément affecté conservera son type, ses attributs et ses styles), de sorte que les deux propriétés contiendront alors le même contenu. . Cependant, certains navigateurs ne respectent plus l'écriture dans innerText et ne vous permettent que d'écraser la propriété textContent (vous ne pouvez pas insérer de balise HTML lors de l'écriture dans ces propriétés, car les caractères spéciaux HTML seront correctement codés à l'aide de références de caractères numériques pour apparaître littéralement , si vous lisez ensuite la propriété innerHTML après l’affectation de innerText ou textContent.

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

Edit (merci à Mark Amery pour le commentaire ci-dessous): Ne le faites de cette manière que si vous savez au-delà de tout doute raisonnable qu'aucun code ne s'appuiera sur la vérification de l'existence de ces propriétés, comme (par exemple) jQuery = fait. Mais si vous utilisez jQuery, vous utiliserez probablement simplement la fonction "text" et ferez $ ('# myElement'). Text ('foo') comme le montrent d'autres réponses.

5
Kwateco

innerText a été ajouté à Firefox et devrait être disponible dans la version FF45: https://bugzilla.mozilla.org/show_bug.cgi?id=264412

Un brouillon de spécification a été rédigé et devrait être intégré au standard de vie HTML à l'avenir: http://rocallahan.github.io/innerText-spec/ , https://github.com/whatwg/html/issues/465

Notez que les implémentations de Firefox, Chrome et IE sont actuellement incompatibles. À l'avenir, nous pouvons probablement nous attendre à ce que Firefox, Chrome et Edge convergent tandis que l'ancien IE reste incompatible.

Voir aussi: https://github.com/whatwg/compat/issues/5

4
Bob

Comme en 2016 depuis Firefox v45, innerText fonctionne sur firefox, consultez son support: http://caniuse.com/#search=innerText

Si vous voulez que cela fonctionne sur les versions précédentes de Firefox, vous pouvez utiliser textContent, qui a un meilleur support sur Firefox mais pire sur les anciennes versions IE : http://caniuse.com/#search=textContent

1
Vandervals

Qu'en est-il quelque chose comme ça?

//$elem is the jQuery object passed along.

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

** J'avais besoin de faire le mien en majuscule.

1
Webmaster G

Cela a été mon expérience avec innerText, textContent, innerHTML et la valeur:

// 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

c'est-à-dire = Internet Explorer, ff = firefox, ch = google chrome. note 1: ff fonctionne jusqu'à ce que, après la suppression de la valeur avec retour arrière - voir la note de Ray Vega ci-dessus. note 2: fonctionne un peu dans chrome - après la mise à jour, il est inchangé, puis vous cliquez à l'écart, puis vous revenez dans le champ et la valeur apparaît. Le meilleur du lot est elem.value = changeVal; que je n'ai pas commenté ci-dessus.

0
gerard

Il suffit de republier des commentaires sous le message original. innerHTML fonctionne dans tous les navigateurs. Merci stefita.

myElement.innerHTML = "foo";

0
Leonid Alzhin