Альтернатива для innerHTML? - PullRequest
       26

Альтернатива для innerHTML?

36 голосов
/ 05 апреля 2009

Мне интересно, есть ли способ изменить текст чего-либо в HTML без использования innerHTML.

Причина, по которой я спрашиваю, заключается в том, что W3C это как бы не одобряет. Я знаю, что это придирчиво, но я просто хочу знать, есть ли способ?

РЕДАКТИРОВАТЬ: люди, кажется, неправильно понимают, что я здесь спрашиваю: я хочу найти способ эффективно изменить отображаемый текст.

Если у меня есть:

<div id="one">One</a>

innerHTML позволяет мне сделать это:

var text = document.getElementsById("one");
text.innerHTML = "Two";

И текст на моем экране изменится.
Я не хочу добавлять больше текста, я хочу изменить уже существующий текст.

Ответы [ 12 ]

36 голосов
/ 05 апреля 2009

Рекомендуется использовать манипуляции с DOM, но это может быть довольно многословно. Например:

// <p>Hello, <b>World</b>!</p>
var para = document.createElement('p');
para.appendChild(document.createTextNode('Hello, '));

// <b>
var b = document.createElement('b');
b.appendChild(document.createTextNode('World');
para.appendChild(b);

para.appendChild(document.createTextNode('!'));

// Do something with the para element, add it to the document, etc.

EDIT

В ответ на ваши изменения, чтобы заменить текущий контент, вы просто удаляете существующий контент, а затем используете приведенный выше код для заполнения нового контента. Например:

var someDiv = document.getElementById('someID');
var children = someDiv.childNodes;
for(var i = 0; i < children.length; i++)
    someDiv.removeChild(children[i]);

Но, как сказал кто-то другой, я бы порекомендовал использовать что-то вроде jQuery, поскольку не все браузеры полностью поддерживают DOM, а те, которые имеют причуды, которые внутренне решаются библиотеками JavaScript. Например, jQuery выглядит примерно так:

$('#someID').html("<p>Hello, <b>World</b>!</p>");
12 голосов
/ 05 апреля 2009

Лучший способ сделать это - использовать document.createTextNode. Одна из основных причин использования этой функции вместо innerHTML заключается в том, что все экранирование HTML-символов позаботится о вас, в то время как вам придется самостоятельно экранировать строку, если вы просто устанавливаете innerHTML.

7 голосов
/ 05 апреля 2009

Если вы хотите изменить только простой текст, есть более быстрое решение, основанное на стандартах:

document.getElementById("one").firstChild.data = "two";

В любом случае, обратите внимание, что innerHTML станет частью будущего стандарта HTML 5.

7 голосов
/ 05 апреля 2009

Вы можете получить тот же эффект, манипулируя DOM. Самый безопасный способ изменить текст - это удалить все дочерние узлы элемента и заменить их новым текстовым узлом.

var node = document.getElementById("one");

while( node.firstChild )
    node.removeChild( node.firstChild );
node.appendChild( document.createTextNode("Two") );

Удаление дочерних узлов избавляет от текстового содержимого вашего элемента перед заменой его новым текстом.

Причина, по которой большинство разработчиков избегают использовать innerHTML, заключается в том, что доступ к элементам через DOM соответствует стандартам.

5 голосов
/ 28 ноября 2010

Simple.

Заменить text.innerHTML = 'two' на text.firstChild.nodeValue = 'two'.

2 голосов
/ 06 апреля 2009
var who=document.getElementById('one'), txt='new text';
if(who.innerText) who.innerText=txt;
else if(who.textContent) who.textContent= txt;

Это может быть нежелательным для вас, как innerHTML, но имеет преимущество в том, что работает в некоторых случаях (IE), где innerHTML или appendChild не имеют, например, некоторые узлы таблицы, текст элементов стиля и элементов сценария и значение формы. поля

1 голос
/ 08 марта 2017

Также ищу хорошую альтернативу обходу element.innerHTML Я наконец нашел это решение:

HTMLElement.prototype.htmlContent = function(html)
{
    var dom = new DOMParser().parseFromString('<template>'+html+'</template>', 'text/html').head;
    this.appendChild(dom.firstElementChild.content);
}

//-- document.getElementById('my-id').innerHTML = string_of_html;
document.getElementById('my-id').htmlContent(string_of_html);

Еще одна альтернатива без тегов, но вместо нее цикл:

HTMLElement.prototype.htmlContent = function(html)
{
    var dom = new DOMParser().parseFromString(html, 'text/html').body;
    while (dom.hasChildNodes()) this.appendChild(dom.firstChild);
}

Имейте в виду, что этот метод на самом деле «добавляет» контент, когда innerHTML «заменяет» контент ...

Это может помочь:

HTMLElement.prototype.clearContent = function()
{
    while (this.hasChildNodes()) this.removeChild(this.lastChild);
}

//-- document.getElementById('my-id').innerHTML = '';
document.getElementById('my-id').clearContent();

документ: https://github.com/swannty/escaping-innerHTML
перф: https://jsperf.com/escaping-innerhtml

1 голос
/ 24 сентября 2011

Хорошо, если я правильно понимаю ваш вопрос, это должен быть ответ.

var text = document.getElementById("one");
//text.innerHTML = "Two";
 text.childNodes[0].nodeValue="two";
1 голос
/ 16 июня 2009

Мне кажется, что комбинация CSS + HTML + JS должна достичь желаемого эффекта:

.myelement:before {   
    content: attr(alt);
} 

...

<span class='myelement' alt='initial value'></span> 

...

element.setAttribute('alt', 'new value'); 

Кто-нибудь знает, работает ли это на практике?

1 голос
/ 05 апреля 2009

Вы можете использовать DOM следующим образом:

<html>
<body>
<div>before</div>
<script type="text/javascript">
var element = document.getElementsByTagName("div")[0];
alert(element.firstChild.nodeValue);
element.removeChild(element.firstChild);
element.appendChild(document.createTextNode('after'));
alert(element.firstChild.nodeValue);
</script>
</body>

Но я думаю, что кто-то редко делает это, но использует фреймворк, такой как jQuery или Prototype или любой другой фреймворк из там . Это пример jquery:

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
</head>
<body>
<div>before</div>
<script type="text/javascript">
var element = $("div");
alert(element.text());
element.text("after");
alert(element.text());
</script>
</body>
...