Dołączanie ciągu HTML do DOM

121

Jak dołączyć ten ciąg HTML

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

do DIV z identyfikatorem 'test'znajdującym się w DOM?

(Btw div.innerHTML += str;jest nie do przyjęcia.)

Šime Vidas
źródło

Odpowiedzi:

243

Użyj, insertAdjacentHTMLjeśli jest dostępny, w przeciwnym razie użyj jakiegoś rodzaju rezerwy. insertAdjacentHTML jest obsługiwany we wszystkich obecnych przeglądarkach .

div.insertAdjacentHTML( 'beforeend', str );

Demo na żywo: http://jsfiddle.net/euQ5n/

Neil
źródło
1
@alex To ta sama koncepcja: parsowanie ciągu HTML i umieszczanie go w DOM. Ale funkcjonalność jest inna - innerHTMLumieszcza napis w elemencie (zastępując wszystkie dzieci), natomiast insertAdjacentHTMLumieszcza go (1) przed elementem, (2) po elemencie, (3) wewnątrz elementu przed pierwszym dzieckiem, lub (4) wewnątrz elementu po ostatnim dziecku.
Šime Vidas,
3
@alex insertAdjacentHTMLjest szybsze niż dołączanie do innerHTML, ponieważ insertAdjacentHTMLnie serializuje i ponownie analizuje istniejących elementów podrzędnych elementu.
hsivonen
2
Ponadto insertAdjacentHTMLutrzymuje wartości odmiennych elementów formy, podczas gdy dodanie do innerHTMLodbudowuje element i traci całą zawartość formy.
Brandon Gano
20

Czy to jest dopuszczalne?

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

jsFiddle .

Ale , odpowiedź Neila jest lepszym rozwiązaniem.

Alex
źródło
1
@ Šime Praca z DOM API zawsze wygląda jak hack: P Czy wolisz odserializować ciąg bez innerHTML ?
Alex
Cóż, tak, jeśli istnieje inny sposób wykorzystania parsera HTML przeglądarki, chciałbym wiedzieć ...
Šime Vidas,
1
@ Šime - Myślę, że są tylko dwa sposoby wykorzystania parsera HTML przeglądarki: innerHTML i document.write. A jeśli myślisz, że innerHTML to hack ...
Alohci,
@Alohci Jest to kolejny sposób: insertAdjacentHTML.
Šime Vidas,
1
@ Šime - dzięki. Znalazłem wersję WHATWG. Znajduje się w specyfikacji DOM Parsing and Serialization . Wskazuje, że oprócz innerHTML i insertAdjacentHTML, istnieje externalHTML i, jak sądzę, createContextualFragment.
Alohci,
16

Występ

AppendChild(E) jest ponad 2x szybsze niż inne rozwiązania na Chrome i Safari, insertAdjacentHTML(F) jest najszybsze na Firefoxie. innerHTML=(B) (nie mylić z +=(A)) jest drugim szybkie rozwiązanie na wszystkich przeglądarkach i jest znacznie bardziej poręczny niż E i F.

Detale

Skonfiguruj środowisko (2019.07.10) MacOs High Sierra 10.13.4 w przeglądarce Chrome 75.0.3770 (64-bitowa), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-bitowa)

wprowadź opis obrazu tutaj

  • w Chrome E (140 tys. operacji na sekundę) jest najszybsze, B (47k) i F (46k) są drugie, A (332) jest najwolniejsze
  • na firefoxie F (94k) jest najszybsze, następnie B (80k), D (73k), E (64k), C (21k) jest najwolniejsze A (466)
  • na Safari E (207k) jest najszybszy, następnie B (89k), F (88k), D (83k), C (25k), najwolniejszy to A (509)

Możesz powtórzyć test na swoim komputerze tutaj

Kamil Kiełczewski
źródło
12

Chodzi o to, aby użyć innerHTMLelementu pośredniego, a następnie przenieść wszystkie jego węzły podrzędne tam, gdzie naprawdę chcesz, aby były przez 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);
}

Pozwala to uniknąć wymazania wszystkich div#testprogramów obsługi zdarzeń, ale nadal umożliwia dołączenie ciągu kodu HTML.

Chris Calo
źródło
3

Właściwy sposób to używanie insertAdjacentHTML. W przeglądarce Firefox starszej niż 8 możesz wrócić do używania, Range.createContextualFragmentjeśli strnie zawiera scripttagów.

Jeśli twoje strzawierają scripttagi, musisz usunąć scriptelementy z fragmentu zwróconego przez createContextualFragmentprzed wstawieniem fragmentu. W przeciwnym razie skrypty będą działać. ( insertAdjacentHTMLoznacza skrypty niewykonalne.)

hsivonen
źródło
Dziękuję za wspomnienie createContextualFragment . Szukałem sposobu, aby niektóre pliki HTML były uruchamiane ze skryptami tylko wtedy, gdy użytkownik zgodzi się ustawić plik cookie.
schliflo
3

Szybki hack :


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

Przypadki użycia :

1: Zapisz jako plik .html i uruchom w przeglądarce Chrome, Firefox lub Edge. (IE nie będzie działać)

2: Użyj w http://js.do

W akcji: http://js.do/HeavyMetalCookies/quick_hack

Podzielone komentarzami:

<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>

Powód, dla którego opublikowałem:

JS.do ma dwie niezbędne cechy:

  1. Brak autouzupełniania
  2. Przyjazny dla monitora pionowego

Ale nie wyświetla komunikatów console.log. Przyjechałem tutaj, szukając szybkiego rozwiązania. Chcę tylko zobaczyć wyniki kilku wierszy kodu brudnopisu, inne rozwiązania to zbyt dużo pracy.

JMI MADISON
źródło
1

Dlaczego jest to niedopuszczalne?

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

byłby podręcznikowym sposobem na zrobienie tego.

Nick Brunt
źródło
4
Zabiłoby to jednak programy obsługi zdarzeń dołączone do #test. Na ogół nie jest to pożądane.
Alex
Ciekawe, że to robi. Nie wydaje się to logiczne.
Nick Brunt,
2
Wydaje mi się, że to logiczne, jeśli myślisz o serializacji kodu HTML do ciągu znaków, a następnie przywróceniu kodu HTML.
Alex
Myślę, że JavaScript musiałby zostać uruchomiony ponownie, aby zresetować program obsługi zdarzeń. Słusznie.
Nick Brunt,
1
@Nick Nie chcesz stringifikować (serializować) części DOM tylko po to, aby móc połączyć ją z innym ciągiem, a następnie przeanalizować całość z powrotem do DOM. Jak powiedział Alex, serializacja nie rejestruje powiązanych programów obsługi zdarzeń (między innymi). Nawet gdyby serializacja mogła uchwycić wszystko, nadal nie chciałbyś tego robić.
Šime Vidas,
0

To może rozwiązać

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');
Rafael Senne
źródło
3
Witamy w przepełnieniu stosu. Wyjaśnij swój kod jako część odpowiedzi, aby podać kontekst, a nie tylko wklejać długi pojedynczy wiersz kodu. Chociaż ty to rozumiesz, inni mogą nie rozumieć, co robi.
pożyczka.burger
0

InnerHTML usuwa wszystkie dane, takie jak zdarzenia dla istniejących węzłów

append child with firstChild dodaje tylko pierwsze dziecko do innerHTML. Na przykład, jeśli musimy dołączyć:

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

pojawi się tylko text1

A co z tym:

dodaje specjalny tag do innerHTML przez dołączenie child, a następnie edytuje externalHTML, usuwając utworzony przez nas tag. Nie wiem, jakie to inteligentne, ale działa dla mnie lub możesz zmienić externalHTML na innerHTML, więc nie musi używać funkcji zastępowania

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>

Łukasz Szpak
źródło
0

Najkrótszy - 18 znaków (nie mylić +=(wspomniane przez OP), =więcej szczegółów tutaj )

test.innerHTML=str

Kamil Kiełczewski
źródło