Додавання рядка HTML до DOM


121

Як додати цей рядок HTML

var str = '<p>Just some <span>text</span> here</p>';

до DIV з ідентифікатором, 'test'який знаходиться в DOM?

(Btw div.innerHTML += str;не прийнятний.)

Відповіді:


243

Використовуйте, insertAdjacentHTMLякщо вона доступна, інакше використовуйте якусь резервну копію. insertAdjacentHTML підтримується у всіх поточних браузерах .

div.insertAdjacentHTML( 'beforeend', str );

Демо-версія: http://jsfiddle.net/euQ5n/


1
@alex Це та сама концепція: розбирати HTML-рядок і вставляти його в DOM. Але функціональність інша - innerHTMLставить рядок у елемент (замінюючи всіх дітей), тоді як insertAdjacentHTMLставить його (1) перед елементом, (2) після елемента, (3) всередині елемента перед першим дочірнім або (4) всередині елемента після останньої дитини.
Šime Vidas

3
@alex insertAdjacentHTMLшвидше, ніж додавати innerHTML, тому insertAdjacentHTMLщо не серіалізує та не переробляє наявні дочірні елементи елемента.
hsivonen

2
Також insertAdjacentHTMLпідтримує значення змінених елементів форми, тоді як додавання до innerHTMLвідновлення елемента та втрачає весь контекст форми.
Брендон Гано

20

Це прийнятно?

var child = document.createElement('div');
child.innerHTML = str;
child = child.firstChild;
document.getElementById('test').appendChild(child);

jsFiddle .

Але , відповідь Нілу є найкращим рішенням.


1
@ Šime Робота з API DOM завжди відчуває себе злому: P Ви б не хотіли видалити рядок без innerHTML ?
алекс

Ну так, якщо є інший спосіб використання HTML-аналізатора браузера, я хотів би знати ...
Šime Vidas

1
@ Šime - Я думаю, що існує лише два способи використання HTML-аналізатора браузера, innerHTML та document.write. І якщо ви думаєте, що innerHTML - це злом ...
Alohci,

@Alohci Там є ще один спосіб: insertAdjacentHTML.
Šime Vidas

1
@ Šime -Дякую Я знайшов версію WHATWG. Це в специфікації DOM Парсінг та серіалізація . Це вказує на те, що, крім InternalHTML та insertAdjacentHTML, існує зовнішнійHTML і, я думаю, створюємо ContextualFragment.
Alohci

16

Продуктивність

AppendChild(E) більш ніж в 2 рази швидше, ніж інші розчини на хромі та сафарі, insertAdjacentHTML(F) найшвидший на Firefox. innerHTML=(B) (не плутати з+= (А)) є другим швидким рішенням у всіх браузерах , і це набагато зручніше , ніж Е і F.

Деталі

Налаштуйте середовище (2019.07.10) MacOs High Sierra 10.13.4 на Chrome 75.0.3770 (64-розрядні), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-розрядні)

введіть тут опис зображення

  • на Chrome E (140k операцій в секунду) найшвидший, B (47k) і F (46k) - другі, A (332) - найповільніший
  • у Firefox F (94k) найшвидший, тоді B (80k), D (73k), E (64k), C (21k) найповільніший - A (466)
  • на Safari E (207k) найшвидший, тоді B (89k), F (88k), D (83k), C (25k), найповільніший - A (509)

Ви можете повторити тест на своєму пристрої тут


12

Ідея полягає в тому, щоб використовувати innerHTMLпосередницький елемент, а потім перемістити всі його дочірні вузли туди, куди ви їх дійсно хочете appendChild.

var target = document.getElementById('test');
var str = '<p>Just some <span>text</span> here</p>';

var temp = document.createElement('div');
temp.innerHTML = str;
while (temp.firstChild) {
  target.appendChild(temp.firstChild);
}

Це дозволяє уникнути стирання будь-яких обробників подій, div#testале все ж дозволяє додавати рядок HTML.


3

Правильний спосіб - це використання insertAdjacentHTML. У Firefox раніше, ніж 8, ви можете перейти до використання, Range.createContextualFragmentякщо у вас strнемає scriptтегів.

Якщо ваші теги strмістять script, вам потрібно видалити scriptелементи, повернуті фрагментом createContextualFragmentперед тим, як вставити фрагмент. Інакше сценарії запускаються. ( insertAdjacentHTMLпозначає сценарії невиконаними.)


Дякую за згадування createContextualFragment . Я шукав спосіб змусити деякі HTML-файли зі скриптами виконуватись лише в тому випадку, якщо користувач погодиться встановити файл cookie.
шліфло

3

Швидкий злом :


<script>
document.children[0].innerHTML="<h1>QUICK_HACK</h1>";
</script>

Використовуйте випадки :

1: Збережіть як .html файл і запустіть у chrome або firefox або edge. (IE звичайна робота)

2: Використовуйте в http://js.do

У дії: http://js.do/HeavyMetalCookies/quick_hack

Розбиті коментарі:

<script>

//: The message "QUICK_HACK" 
//: wrapped in a header #1 tag.
var text = "<h1>QUICK_HACK</h1>";

//: It's a quick hack, so I don't
//: care where it goes on the document,
//: just as long as I can see it.
//: Since I am doing this quick hack in
//: an empty file or scratchpad, 
//: it should be visible.
var child = document.children[0];

//: Set the html content of your child
//: to the message you want to see on screen.
child.innerHTML = text;

</script>

Причина, чому я розмістив:

JS.do має два must-have:

  1. Немає автозаповнення
  2. Вертикальний монітор

Але не відображаються повідомлення console.log. Сюди прийшли шукати швидкого рішення. Я просто хочу побачити результати кількох рядків коду скретчпад, інші рішення - це занадто багато роботи.


1

Чому це не прийнятно?

document.getElementById('test').innerHTML += str

був би підручник способом це зробити.


4
Це вбило б обробників подій, приєднаних до цього #test. Це взагалі небажано.
alex

Цікаво, що це робить. Насправді це не логічно.
Нік Брунт

2
Логічно, я думаю, якщо ви думаєте про серіалізацію HTML в рядок, а потім про повернення HTML назад.
алекс

Я думаю, що JavaScript потрібно було б запустити знову, щоб скинути обробник подій. Досить справедливо.
Нік Брунт

1
@Nick Ви не хочете впорядковувати (серіалізувати) частину DOM лише для того, щоб ви могли об'єднати її з іншим рядком, а потім проаналізувати всю справу назад у DOM. Як сказав Алекс, серіалізація не буде фіксувати пов'язані обробники подій (серед іншого). Навіть якщо б серіалізація могла захопити все, ви все одно не хотіли б цього робити.
Šime Vidas

0

Це може вирішити

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');

3
Ласкаво просимо до переповнення стека. Будь ласка, поясніть свій код як частину відповіді, щоб надати певний контекст, а не просто вставити довгий рядок коду. Хоча ви це розумієте, інші можуть не розуміти, що це робить.
позика.бургер

0

InnerHTML очистить усі дані, такі як подія для існуючих вузлів

додавання дитини до firstChild додає лише перший дитина до innerHTML. Наприклад, якщо нам потрібно додати:

 <p>text1</p><p>text2</p>

відобразиться лише текст1

Як що до цього:

додає спеціальний тег до innerHTML додаванням дочірньої програми, а потім редагує externalHTML, видаляючи створений нами тег. Не знаю, наскільки він розумний, але він працює для мене, або ви можете змінити externalHTML на innerHTML, тому не потрібно використовувати функцію заміни

function append(element, str)
{

  var child = document.createElement('someshittyuniquetag');
		
  child.innerHTML = str;

  element.appendChild(child);

  child.outerHTML = child.outerHTML.replace(/<\/?someshittyuniquetag>/, '');

// or Even child.outerHTML = child.innerHTML


  
}
<div id="testit">
This text is inside the div
<button onclick="append(document.getElementById('testit'), '<button>dadasasdas</button>')">To div</button>
<button onclick="append(this, 'some text')">to this</button>
</div>


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.