Как заменить текст внутри элемента div?


166

Мне нужно установить текст внутри элемента DIV динамически. Каков наилучший подход, безопасный для браузера? У меня есть prototypejs и scriptaculous.

<div id="panel">
  <div id="field_name">TEXT GOES HERE</div>
</div>

Вот как будет выглядеть функция:

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById('field_name');
  //Make replacement here
}

Делает ли принятый ответ то, что вам нужно, когда назначенный текст выглядит следующим образом: - <span style = "font-size: 36pt"> Это большой размер </ span>. Если такое поведение желательно, можете ли вы перефразировать вопрос для соответствия?
AnthonyWJones

Может ли это быть использовано в XSS-инъекции?
Джеймс Вестгейт

Ответы:


49

Я бы использовал updateметод Prototype, который поддерживает простой текст, фрагмент HTML или любой объект JavaScript, который определяет toStringметод.

$("field_name").update("New text");

26
@Aeyoun ОП подразумевал, что они уже использовали Prototype, поэтому, если это так, имеет смысл воспользоваться этим.
Джон Топли

6
Почему до меня только работает$("field_name").text("new text");
Драко

@Drako Вы используете PrototypeJS?
Джон Топли

10
@Drako Оригинальный вопрос и мой ответ от семи лет назад для PrototypeJS, а не jQuery.
Джон Топли

255

Вы можете просто использовать:

fieldNameElement.innerHTML = "My new text!";

2
Не следует ли использовать одинарные кавычки для «статического» текста?
Милан Бабушков

5
В PHP да. В JavaScript я не верю, что это имеет значение.
ceejayoz

46
В Javascript одинарные и двойные кавычки являются взаимозаменяемыми.
17 из 26

18
плохой совет, потому что текст может случайно содержать контент, похожий на HTML-разметку
Trident D'Gao

10
element.innerHTML = "<script>doSomethingMalicious()</script>";не будет хорошей идеей element.innerHTML = "& neither will this";
Джозеф Нилдс

175

Обновлено для всех, кто читает это в 2013 году и позже:

Этот ответ имеет много SEO, но все ответы сильно устарели и зависят от библиотек, чтобы делать то, что все современные браузеры делают из коробки.

Чтобы заменить текст внутри элемента div, используйте Node.textContent, который предоставляется во всех текущих браузерах.

fieldNameElement.textContent = "New text";

10
@Legolas Поэтому пишу «текущий браузер» два года назад.
mikemaccana

2
Спасибо! Я пробовал другие ответы, удивляясь, почему «innerHTML» не работает.
GreySage

2
Вы могли бы рассмотреть вопрос о том, почему textContentэто лучший метод innerHTML: он быстрее, безопаснее и более уместен, когда не намеренно пытается вставить HTML-разметку.
CertainPerformance

75

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById("field_name");
  while(fieldNameElement.childNodes.length >= 1) {
    fieldNameElement.removeChild(fieldNameElement.firstChild);
  }
  fieldNameElement.appendChild(fieldNameElement.ownerDocument.createTextNode(fieldName));
}

Преимущества этого:

  1. Он использует только DOM, поэтому метод переносим на другие языки и не использует нестандартный innerHTML
  2. fieldName может содержать HTML, который может быть попыткой атаки XSS. Если мы знаем, что это просто текст, мы должны создать текстовый узел вместо того, чтобы браузер анализировал его на HTML

Если бы я собирался использовать библиотеку javascript, я бы использовал jQuery и сделал бы это:


  $("div#field_name").text(fieldName);

Обратите внимание, что комментарий @AnthonyWJones является правильным: «field_name» не является особенно описательным идентификатором или именем переменной.


На какие другие языки вы могли бы перенести эту технику?
Джон Топли

Любой язык с реализацией DOM поддерживает это (и большинство языков имеют реализацию DOM).
Квентин,

Это хороший ответ, лучше, чем мой, и это правильный ответ. Вы могли бы рассмотреть возможность привести пример в порядок. 'fieldname' не является хорошим именем для параметра функции. На самом деле, может быть лучше взять два - один для идентификатора элемента, а другой - для контента, т.е. elemID, контент
AnthonyWJones

Я позаимствовал fieldName и ID из самого вопроса.
Даниэль Папасян

Вопрос, вероятно, использовал field_name, чтобы сделать пример общим. Также спрашивающий упоминает, что Prototype доступен, но не jQuery.
Джон Топли

17
$('field_name').innerHTML = 'Your text.';

Одна из замечательных особенностей Prototype - $('field_name')это то же самое, что иdocument.getElementById('field_name') . Используй это! :-)

Ответ Джона Топли с использованием updateфункции Prototype - еще одно хорошее решение.


4
Это не похоже на JavaScript?
Милан Бабушков

1
Не используйте innerHTML. Это не рекомендация w3c и ведет себя непоследовательно. Это считается плохим стилем.
Том

Том, что следует использовать вместо этого (если вы не используете Prototype)?
Милан Бабушков

1
Милан, более приемлемый способ - циклически перебирать childNodes, вызывать removeNode (true) для каждого, а затем добавлять новые узлы, созданные с помощью document.createElement () или document.createTextNode (). Если вам нужно сделать это, я бы порекомендовал написать функцию, чтобы избежать много печатать.
Джоэл Анаир

3
@RaduSimionescu Нет, это не так. Этот вопрос и ответ о Prototype.js, а не jQuery. В Prototype $ищет элемент по идентификатору. Это не на основе селекторов, как JQuery. api.prototypejs.org/dom/dollar
ceejayoz

15

Быстрый ответ заключается в использовании innerHTML (или метода обновления прототипа, который почти идентичен). Проблема с innerHTML в том, что вам нужно экранировать назначаемый контент. В зависимости от ваших целей вам нужно будет сделать это с другим кодом ИЛИ

в IE: -

document.getElementById("field_name").innerText = newText;

в ФФ: -

document.getElementById("field_name").textContent = newText;

(На самом деле FF имеют следующий код)

HTMLElement.prototype.__defineGetter__("innerText", function () { return this.textContent; })

HTMLElement.prototype.__defineSetter__("innerText", function (inputText) { this.textContent = inputText; })

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


7

Если вы действительно хотите, чтобы мы просто продолжили с того места, где вы остановились, вы можете сделать:

if (fieldNameElement)
    fieldNameElement.innerHTML = 'some HTML';

5

nodeValue также является стандартным свойством DOM, которое вы можете использовать:

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById(field_name);
  if(fieldNameElement.firstChild)
    fieldNameElement.firstChild.nodeValue = "New Text";
}


1

Если вы склонны начать использовать много JavaScript на своем сайте, jQuery сделает игру с DOM чрезвычайно простой.

http://docs.jquery.com/Manipulation

Делает это так же просто, как: $ ("# field-name"). Text ("Некоторый новый текст.");


Прототип имеет аналогичные функции полезности.
ceejayoz


0
function showPanel(fieldName) {
  var fieldNameElement = document.getElementById(field_name);

  fieldNameElement.removeChild(fieldNameElement.firstChild);
  var newText = document.createTextNode("New Text");
  fieldNameElement.appendChild(newText);
}

Лучше заменить узел, чем удалить его и добавить новый как две отдельные операции.
Квентин,

0

Вот простой способ jQuery :

var el = $('#yourid .yourclass');

el.html(el.html().replace(/Old Text/ig, "New Text"));

Это кажется плохой идеей - что, если ваш элемент содержит подузлы с тем же текстом или ваш текст соответствует части имени тега элемента? Почему не просто использовать .text?
Джеймс Вестгейт

Я полностью согласен с Джеймсом Вестгейтом, не стоит этого делать.
TGarrett

0

В HTML вставьте это

<div id="field_name">TEXT GOES HERE</div>

В JavaScript положи это

var fieldNameElement = document.getElementById('field_name');
        if (fieldNameElement)
        {fieldNameElement.innerHTML = 'some HTML';}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.