javascript cross - 'innerText' funciona en IE, pero no en Firefox




browser testing (13)

Tengo un código JavaScript que funciona en IE y contiene lo siguiente:

myElement.innerText = "foo";

Sin embargo, parece que la propiedad 'innerText' no funciona en Firefox. ¿Hay algún equivalente de Firefox? ¿O hay una propiedad de navegador más genérica que se puede usar?


Answers

jQuery proporciona un método .text() que se puede utilizar en cualquier navegador. Por ejemplo:

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

También es posible emular el comportamiento de texto innerText en otros navegadores:

 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");
         }
     });
 }

Una línea realmente simple de Javascript puede obtener el texto "no etiquetado" en todos los navegadores principales ...

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

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

Editar (gracias a Mark Amery por el comentario a continuación): Solo hágalo de esta manera si sabe más allá de una duda razonable que ningún código se basará en verificar la existencia de estas propiedades, como (por ejemplo) jQuery . Pero si está usando jQuery, probablemente solo use la función "texto" y haga $ ('# myElement'). Text ('foo') como muestran otras respuestas.


Tenga en cuenta que la propiedad Element::innerText no contendrá el texto que se ha ocultado con el estilo CSS " display:none " en Google Chrome (y también eliminará el contenido que ha sido enmascarado por otras técnicas CSS (incluido el tamaño de la fuente: 0, color: transparente, y algunos otros efectos similares que hacen que el texto no se represente de ninguna manera visible).

Otras propiedades de CSS también se consideran:

  • Primero se analiza el estilo de "visualización:" de los elementos internos para determinar si delimita un contenido de bloque (como "pantalla: bloque", que es el valor predeterminado de los elementos de bloque HTML en la hoja de estilos incorporada del navegador, y cuyo comportamiento no ha sido reemplazado por tu propio estilo CSS); si es así, se insertará una nueva línea en el valor de la propiedad innerText. Esto no sucederá con la propiedad textContent.
  • También se considerarán las propiedades CSS que generan contenidos en línea: por ejemplo, el elemento en línea <br \> que genera una nueva línea en línea también generará una nueva línea en el valor de texto interior.
  • El estilo "display: inline" no causa ninguna nueva línea en textContent o innerText.
  • El estilo "display: table" genera nuevas líneas alrededor de la tabla y entre las filas de la tabla, pero "display: table-cell" generará un carácter de tabulación.
  • La propiedad "position: absolute" (utilizada con display: block o display: inline, no importa) también hará que se inserte un salto de línea.
  • Algunos navegadores también incluirán una única separación de espacio entre intervalos.

Pero Element::textContent seguirá conteniendo TODOS los contenidos de los elementos de texto interno independientemente del CSS aplicado, incluso si son invisibles. Y no se generarán nuevas líneas o espacios en blanco adicionales en textContent, que simplemente ignora todos los estilos y la estructura y los tipos de elementos internos en línea / bloque o posicionados.

Una operación de copiar / pegar con la selección del mouse descartará el texto oculto en el formato de texto sin formato que se coloca en el portapapeles, por lo que no contendrá todo en el contenido de textContent , sino solo lo que está dentro del innerText interior (después de la generación de espacios en blanco / nueva línea como encima).

Ambas propiedades son compatibles con Google Chrome, pero su contenido puede ser diferente. Los navegadores más antiguos todavía incluían en todo el texto, como lo que ahora contiene el contenido de texto (pero su comportamiento en relación con la generación de espacios en blanco / nuevas líneas era inconsistente).

jQuery resolverá estas inconsistencias entre los navegadores utilizando el método ".text ()" agregado a los elementos analizados que devuelve a través de una consulta $ (). Internamente, resuelve las dificultades buscando en el DOM de HTML, trabajando solo con el nivel de "nodo". Así que devolverá algo parecido al contenido de texto estándar.

La advertencia es que este método jQuery no insertará ningún espacio adicional o saltos de línea que puedan ser visibles en la pantalla causados ​​por subelementos (como <br /> ) del contenido.

Si diseña algunos scripts para accesibilidad y su hoja de estilo se analiza para una representación no auditiva, como los complementos utilizados para comunicarse con un lector de Braille, esta herramienta debe usar el contenido de texto si debe incluir los signos de puntuación específicos que se agregan en intervalos de estilos. "display: none" y que normalmente se incluyen en las páginas (por ejemplo, para superíndices / subíndices), de lo contrario, el texto interior será muy confuso en el lector de Braille.

Los textos ocultos por los trucos de CSS ahora generalmente son ignorados por los principales motores de búsqueda (que también analizarán el CSS de sus páginas HTML y también ignorarán los textos que no tienen colores de contraste en el fondo) usando un analizador HTML / CSS y la propiedad DOM "texto interior" exactamente como en los navegadores visuales modernos (al menos este contenido invisible no se indexará, por lo que el texto oculto no se puede usar como un truco para forzar la inclusión de algunas palabras clave en la página para verificar su contenido); pero este texto oculto seguirá mostrándose en la página de resultados (si la página aún estaba calificada del índice para incluirla en los resultados), usando la propiedad "textContent" en lugar del HTML completo para eliminar los estilos y scripts adicionales.

Si asigna texto sin formato en cualquiera de estas dos propiedades, esto sobrescribirá el marcado interno y los estilos aplicados (solo el elemento asignado conservará su tipo, atributos y estilos), por lo que ambas propiedades contendrán el mismo contenido . Sin embargo, algunos navegadores ahora ya no aceptarán la escritura en texto interior, y solo le permitirán sobrescribir la propiedad textContent (no puede insertar el código HTML al escribir en estas propiedades, ya que los caracteres especiales HTML se codificarán correctamente usando referencias numéricas de caracteres para que aparezcan literalmente , si luego lees la propiedad innerHTML después de la asignación de innerText o textContent .


Encontré esto aquí:

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

innerText se ha agregado a Firefox y debería estar disponible en la versión FF45: https://bugzilla.mozilla.org/show_bug.cgi?id=264412

Se ha escrito un borrador de especificación y se espera que se incorpore al estándar de vida HTML en el futuro: http://rocallahan.github.io/innerText-spec/ , https://github.com/whatwg/html/issues/465

Tenga en cuenta que actualmente las implementaciones de Firefox, Chrome e IE son todas incompatibles. En el futuro, probablemente podamos esperar que Firefox, Chrome y Edge converjan mientras que el antiguo IE sigue siendo incompatible.

Consulte también: https://github.com/whatwg/compat/issues/5



Esta ha sido mi experiencia con innerText , textContent , innerHTML y value:

// 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. nota 1: ff funciona hasta después de que el valor se elimine con retroceso - vea la nota de Ray Vega arriba. Nota 2: funciona un poco en Chrome: después de la actualización no se modifica, haga clic en el botón de distancia, haga clic en el campo y aparecerá el valor. Lo mejor del lote es elem.value = changeVal ; que no he comentado anteriormente.


Según la respuesta de Prakash K, Firefox no admite la propiedad innerText. Por lo tanto, simplemente puede probar si el agente de usuario admite esta propiedad y proceder de la siguiente manera:

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

Si solo necesita configurar el contenido de texto y no recuperarlo, aquí tiene una versión trivial de DOM que puede usar en cualquier navegador; no requiere la extensión de texto interno de IE ni la propiedad de contenido de texto de DOM Level 3 Core.

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

Actualización : escribí una publicación en el blog que detallaba todas las diferencias mucho mejor.

Firefox usa el Node::textContent estándar de W3C Node::textContent , pero su comportamiento difiere "levemente" del del texto innerText propietario de innerText (también copiado por Opera, hace algún tiempo, entre docenas de otras características de MSHTML).

En primer lugar, la representación de espacios en blanco de textContent es diferente de la de innerText . Segundo, y más importante, textContent incluye todos los contenidos de la etiqueta SCRIPT , mientras que innerText no lo hace.

Para hacer las cosas más entretenidas, Opera, además de implementar el contenido de texto estándar, decidió agregar también el texto innerText de MSHTML, pero lo cambió para que actuara como contenido de textContent , es decir, que incluyera contenidos SCRIPT (de hecho, el contenido de textContent y contenido innerText de Opera parecen producir resultados idénticos, probablemente alias entre sí).

textContent es parte de la interfaz del Node , mientras que innerText es parte de HTMLElement . Esto, por ejemplo, significa que puede "recuperar" innerText de texto pero no texto innerText de los nodos de texto:

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

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

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

Finalmente, Safari 2.x también tiene innerText implementación de texto innerText con errores. En Safari, innerText funciona correctamente solo si un elemento no está oculto (a través de style.display == "none" ) ni está huérfano del documento. De lo contrario, innerText da innerText resultado una cadena vacía.

Estaba jugando con textContent abstraction (para textContent estas deficiencias), pero resultó ser bastante complejo .

Lo mejor que puedes hacer es definir primero tus requisitos exactos y seguir desde allí. A menudo es posible simplemente quitar las etiquetas del innerHTML de un elemento, en lugar de tratar todas las posibles desviaciones de innerText textContent / contenido innerText .

Otra posibilidad, por supuesto, es recorrer el árbol DOM y recopilar nodos de texto de forma recursiva.


Hice este formateador muy simple, es cut / n / pastable (actualizado con una versión más limpia):

function DateFmt(fstr) {
  this.formatString = fstr

  var mthNames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  var dayNames = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
  var zeroPad = function(number) {
     return ("0"+number).substr(-2,2);
  }

  var dateMarkers = {
    d:['getDate',function(v) { return zeroPad(v)}],
    m:['getMonth',function(v) { return zeroPad(v+1)}],
    n:['getMonth',function(v) { return mthNames[v]; }],
    w:['getDay',function(v) { return dayNames[v]; }],
    y:['getFullYear'],
    H:['getHours',function(v) { return zeroPad(v)}],
    M:['getMinutes',function(v) { return zeroPad(v)}],
    S:['getSeconds',function(v) { return zeroPad(v)}],
    i:['toISOString']
  };

  this.format = function(date) {
    var dateTxt = this.formatString.replace(/%(.)/g, function(m, p) {
      var rv = date[(dateMarkers[p])[0]]()

      if ( dateMarkers[p][1] != null ) rv = dateMarkers[p][1](rv)

      return rv

    });

    return dateTxt
  }

}

fmt = new DateFmt("%w %d:%n:%y - %H:%M:%S  %i")
v = fmt.format(new Date())

http://snipplr.com/view/66968.82825/





javascript internet-explorer firefox cross-browser