"innerText" работает в IE, но не в Firefox

У меня есть код JavaScript, который работает в IE, содержащий следующее:

myElement.innerText = "foo";

однако, похоже, что свойство "innerText" не работает в Firefox. Есть в Firefox аналог? Или есть более общее свойство кросс-браузера, которое можно использовать?

15 ответов


Firefox использует в W3C-совместимых textContent собственность.

Я бы предположил, что Safari и Opera также поддерживают это свойство.


обновление: я написал сообщение в блоге подробно все различия намного лучше.


Firefox использует стандарт W3C Node::textContent, но его поведение "немного" отличается от поведения собственности MSHTML innerText (скопировано Opera также, некоторое время назад, среди десятков других функций MSHTML).

прежде всего,textContent представление пробелов отличается от innerText один. Во-вторых, и что более важно, textContent включает все содержимое тега скрипта, тогда как внутренний текст-нет.

просто чтобы сделать вещи более интересными, Opera-помимо реализации стандарта textContent - решил также добавить MSHTML в innerText но изменил его в качестве textContent - т. е. включая содержимое скрипта (на самом деле,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

Наконец-То, Сафари-2.x также имеет багги innerText реализация. В Safari, innerText работает только если элемент ни скрытый (через style.display == "none") ни осиротел от документа. В противном случае, innerText приводит к пустой строке.

я играл с textContent абстракция (чтобы обойти эти недостатки), но это оказалось довольно сложный.

вам лучше сделать ставку на сначала определите свои точные требования и следовать оттуда. Часто можно просто снять теги с innerHTML элемента, а не заниматься всеми возможными textContent/innerText отклонения.

другая возможность, конечно же, состоит в том, чтобы ходить по дереву DOM и рекурсивно собирать текстовые узлы.


Если вам нужно только установить текстовое содержимое, а не получить, вот тривиальная версия DOM, которую вы можете использовать в любом браузере; она не требует расширения IE innerText или свойства DOM Level 3 Core textContent.

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

jQuery предоставляет .text() метод, который можно использовать в любом браузере. Например:

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

в соответствии с ответом Prakash K Firefox не поддерживает свойство innerText. Таким образом, вы можете просто проверить, поддерживает ли агент пользователя это свойство и действовать соответственно, как показано ниже:

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

очень простой строку JavaScript может получить "не-taggy" текст во всех основных браузерах...

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

отметим, что Element::innerText недвижимость не содержит текст, который был скрыт стилем CSS"display:none " в Google Chrome (а также он отбросит контент, который был замаскирован другой техникой CSS (включая размер шрифта:0, цвет:прозрачный и несколько других подобных эффектов, которые заставляют текст не отображаться каким-либо видимым образом).

другие свойства CSS также рассматриваются:

  • сначала стиль" display: "внутренних элементов анализируется, чтобы определить, ограничивает ли он содержимое блока (например, "display:block", который является значением по умолчанию элементов HTML-блока во встроенной таблице стилей браузера и поведение которого не было переопределено вашим собственным стилем CSS); если это так, новая строка будет вставлена в значение свойства innerText. Этого не произойдет с свойством textContent.
  • также будут рассмотрены свойства CSS, которые генерируют встроенное содержимое : например, встроенный элемент <br \>, что создает встроенная новая строка также будет генерировать новую строку в значении innerText.
  • стиль "display:inline" не вызывает новой строки ни в textContent, ни в innerText.
  • стиль "display:table"генерирует новые строки вокруг таблицы и между строками таблицы, но" display:table-cell " генерирует символ табуляции.
  • свойство "position:absolute" (используется с display: block или display:inline, это не имеет значения) также вызовет разрыв строки вставленный.
  • некоторые браузеры также будут включать в себя одно пространство между промежутками

но Element::textContent по-прежнему будет содержать все содержимое внутренних текстовых элементов независимо от применяемого CSS, даже если они невидимы. И никакие дополнительные новые строки или пробелы не будут генерироваться в textContent, который просто игнорирует все стили и структуру и встроенные/блочные или позиционированные типы внутренних элементов.

операции копирования/вставки с помощью мыши будет отбрасывать скрытый текст в формате обычного текста, который помещается в буфер обмена, поэтому он не будет содержать все в textContent, но только то, что находится внутри innerText (после пробела / генерации новой строки, как указано выше).

оба свойства затем поддерживаются в Google Chrome, но их содержимое может быть различным. Старые браузеры все еще включали в innetText все, что теперь содержит textContent (но их поведение в отношении генерации пробелов / новых строк было inconsistant).

jQuery решит эти несоответствия между браузерами с помощью ".text () " метод, добавленный к анализируемым элементам, он возвращает через запрос $ (). Внутренне он решает трудности, заглядывая в HTML DOM, работая только с уровнем "узла". Таким образом, он вернет что-то похожее на стандартный textContent.

предостережение заключается в том, что этот метод jQuery не будет вставлять никаких дополнительных пробелов или разрывов строк, которые могут быть видны на экран, вызванный подэлементами (например,<br />) контент.

если вы разрабатываете некоторые скрипты для специальных возможностей, и ваша таблица стилей анализируется для не-звукового рендеринга, например Плагины, используемые для связи с читателем Брайля, этот инструмент должен использовать textContent, если он должен включать определенные знаки препинания, которые добавляются в промежутках, стилизованных под "display: none" и которые обычно включены в страницы (например, для надстрочных/подстрочных), в противном случае внутренний текст будет очень confusive на брайлевском читателя.

тексты, скрытые трюками CSS, теперь обычно игнорируются основными поисковыми системами (которые также будут анализировать CSS ваших HTML-страниц, а также игнорировать тексты, которые не находятся в контрастных цветах на фоне) с помощью синтаксического анализатора HTML / CSS и свойства DOM "innerText" точно так же, как в современных визуальных браузерах (по крайней мере, этот невидимый контент не будет индексироваться, поэтому скрытый текст не может быть использован в качестве трюка для принудительного включения некоторых ключевых слов но этот скрытый текст будет по-прежнему отображаться на странице результатов (если страница все еще была квалифицирована из индекса, который будет включен в результаты), используя свойство "textContent" вместо полного HTML для удаления дополнительных стилей и скриптов.

если вы назначите какой-либо простой текст в любом из этих двух свойств, это перезапишет внутреннюю разметку и применяемые к ней стили (только назначенный элемент сохранит свой тип, атрибуты и стили), поэтому оба свойства будут содержать то же содержимое. Однако некоторые браузеры больше не будут выполнять запись в innerText и позволят вам перезаписать только свойство textContent (вы не можете вставлять HTML-разметку при записи в эти свойства, так как специальные символы HTML будут правильно закодированы, используя числовые ссылки символов, чтобы появиться буквально, если вы затем прочитаете innerHTML свойство после присвоения innerText или textContent.


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

Edit (спасибо Марку Эмери за комментарий ниже): только сделайте это таким образом, если вы знаете, вне разумных сомнений, что никакой код не будет полагаться на проверку существования этих свойств, например (например)jQuery делает. Но если вы используете jQuery, вы, вероятно, просто используете функцию "text" и делаете $('#myElement').текст ("foo"), как показывают некоторые другие ответы.


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


Как насчет чего-то подобного?

//$elem is the jQuery object passed along.

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

* * Мне нужно было сделать свой верхний регистр.


как в 2016 году из 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: работает несколько в chrome-после обновления он остается неизменным, затем вы щелкаете и щелкаете обратно в поле, и появляется значение. Лучший из них -elem.value = changeVal;, которые я не комментировал выше.


просто перепечатка из комментариев под оригинальным сообщением. innerHTML работает во всех браузерах. Спасибо stefita.

myElement.innerHTML = "foo";


нашел это вот:

<!--[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 поведение в других браузерах:

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