Кросс-браузерный внутренний текст для установки значений

Скажем, у меня есть следующий код:

<html>
  <head></head>
  <body>
   <div id="d">some text</div>

  <script type="text/javascript">
    var d = document.getElementByid('d');
    var innerText = d.innerText || d.textContent;

    innerText = 'new text';
  </script>
  </body>
</html>

И я хочу изменить текстовое значение для тега div с id = 'd'. К сожалению, код блока выше не работает, и текстовое содержимое не изменяется.

Он работает, если делает следующий рецепт:

if (d.innerText) d.innerText = 'new text';
else d.textContent = 'new text';

Но мне не нравится рецепт выше, потому что он не компактный.

Есть ли у вас какие-либо предложения, почему первый подход не работает?

Ответ 1

Вместо нескольких назначений вы можете захватить свойство и использовать его

var text = ('innerText' in d)? 'innerText' : 'textContent';
d[text] = 'New text';

Ответ 2

Первый подход не работает, потому что все, что он делает, устанавливает переменную в новое значение, она не записывает значение в элемент. Строка

var innerText = d.innerText || d.textContent;

... устанавливает переменную innerText в значение свойства text, которое она находит, это не ссылка на фактическое свойство.

Вам нужно будет сделать ветку, например:

var d = document.getElementById('d');
var msg = "new text";
if ("innerText" in d) {
    d.innerText = msg;
}
else {
    d.textContent = msg;
}

Эта функция - определяет, использует ли браузер innerText или textContent, ища существование свойства в элементе (что делает оператор in, проверяет, обладает ли объект свойством с заданным именем, даже если это свойство пустое, null, undefined и т.д.).

Вы даже можете написать для себя функцию:

var setText = (function() {
    function setTextInnerText(element, msg) {
        element.innerText = msg;
    }

    function setTextTextContent(element, msg) {
        element.textContent = msg;
    }

    return "innerText" in document.createElement('span') ? setTextInnerText : setTextTextContent;
})();

Это делает обнаружение функции один раз и возвращает функцию, для которой вам понадобится любой полупристойный движок.

Или поочередно, если вы хотите, чтобы разметка HTML в сообщении обрабатывалась как разметка (а не буквальный текст), вы можете просто использовать innerHTML (что является согласованным во всех браузерах). Но опять же, если вы используете innerHTML, будет обрабатываться разметка, которая может быть не такой, какой вы хотите.


Мне полезно использовать хорошую библиотеку JavaScript для решения этих различий браузера (и предоставить массу полезных дополнительных функций), например jQuery, YUI, Closure, или любой из нескольких других. Очевидно, вы ничего не можете сделать с библиотекой, с которой вы не можете обойтись без нее, это просто вопрос, стоящий на плечах людей, которые уже проделали огромную работу.: -)

В этом случае, например, использование jQuery выше:

$("#d").text("new text");

Что это.

Ответ 3

d.appendChild(document.createTextNode("new text");

Ответ 4

вы можете использовать только textContent, и он будет работать в основных браузерах... (FF, Safari и Chrome)

var d = document.getElementById('d');
var msg = "new text";
d.textContent = msg;