Wstawianie elementów HTML z JavaScriptem


105

Zamiast żmudnego wyszukiwania obejść dla każdego typu atrybutu i zdarzenia, używając następującej składni:

elem = document.createElement("div");
elem.id = 'myID';
elem.innerHTML = ' my Text '
document.body.insertBefore(elem,document.body.childNodes[0]);

Czy istnieje sposób, w jaki mogę po prostu zadeklarować cały element HTML jako ciąg? lubić:

elem = document.createElement("<div id='myID'> my Text </div>");
document.body.insertBefore(elem,document.body.childNodes[0]);

Odpowiedzi:


124

Zamiast bezpośrednio bawić się innerHTML, lepiej byłoby utworzyć fragment, a następnie wstawić to:

function create(htmlStr) {
    var frag = document.createDocumentFragment(),
        temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    while (temp.firstChild) {
        frag.appendChild(temp.firstChild);
    }
    return frag;
}

var fragment = create('<div>Hello!</div><p>...</p>');
// You can use native DOM methods to insert the fragment:
document.body.insertBefore(fragment, document.body.childNodes[0]);

Korzyści:

  1. Możesz użyć natywnych metod DOM do wstawiania, takich jak insertBefore, appendChild itp.
  2. Masz dostęp do rzeczywistych węzłów DOM przed ich wstawieniem; możesz uzyskać dostęp do obiektu childNodes fragmentu.
  3. Korzystanie z fragmentów dokumentów jest bardzo szybkie; szybciej niż tworzenie elementów poza DOM, aw niektórych sytuacjach szybciej niż innerHTML.

Mimo że innerHTMLjest używany w funkcji, wszystko dzieje się poza DOM, więc jest znacznie szybsze niż myślisz ...


3
Założę się, że ta metoda createDocumentFragment () nie byłaby tak dobra jak „legacy” innerHTML.
TheFlash

2
Ta metoda działa we wszystkich nowoczesnych przeglądarkach. W przypadku przeglądarki IE 5.5 i starszych możesz sprawdzić, jak :: if (document.createDocumentFragment) {create ('...'); } else {/ * Być może użyj innerHTML * /}
James

32
crescentfresh, pomagam w SO, ponieważ lubię pomagać ludziom; Przepraszam, jeśli rozwiązanie nie działa w 100% we wszystkich sytuacjach. Jeśli jesteś tak zaniepokojony, dlaczego nie zaproponować własnego rozwiązania, zamiast niepotrzebnie krytykować już oferowane odpowiedzi? Przy każdej abstrakcji zawsze będą przypadki skrajne! To jest środowisko uczenia się - nie jesteśmy tutaj, aby dawać ludziom rozwiązanie na talerzu - jesteśmy tutaj, aby pomagać sobie nawzajem w stawaniu się lepszymi w tym, co robimy! Przepraszam, ale gdzie ktoś wspomniał o „AJAX”?
James

1
Słusznie. Przepraszam. Po prostu czuję, że jest tu tak wiele abstrakcji bez wspomnianych zastrzeżeń.
Crescent Fresh

1
to jest o wiele bardziej skomplikowane, niż powinno być - odpowiedź sime vidas jest znacznie lepsza
JonnyRaa,

83

Chcesz to

document.body.insertAdjacentHTML( 'afterbegin', '<div id="myID">...</div>' );

13
nie wiem, dlaczego nie jest to akceptowana odpowiedź. To jest o wiele prostsze i bardziej oczywiste
JonnyRaa,

@JonnyLeeds to nie działa na bodyelemencie, ale działa dobrze na każdym innym elemencie.
Phill

1
@Phill Oczywiście, że działa <body>. Prawdę mówiąc, uruchamianie go na nim <body>jest moją standardową metodą wprowadzania elementów takich jak arkusze stylów do stron internetowych za pośrednictwem konsoli. Jaki masz problem?
Šime Vidas,

@ ŠimeVidas prawdopodobnie dlatego, że element body nie był zdefiniowany w czasie wykonywania ... sparowałem twoją linię z window.onload = function () {…}, aby zapobiec temu problemowi
GDY

@Grandy Phill napisał, że działa na innych elementach. Gdyby <body>było niezdefiniowane, tak samo byłoby ze wszystkimi innymi elementami, więc prawdopodobnie nie jest to problem Philla.
Šime Vidas

32

Spójrz na insertAdjacentHTML

var element = document.getElementById("one");
var newElement = '<div id="two">two</div>'
element.insertAdjacentHTML( 'afterend', newElement )
// new DOM structure: <div id="one">one</div><div id="two">two</div>

pozycja to pozycja względem wstawianego elementu, obok którego:

„beforebegin” Przed samym elementem

'afterbegin' Tylko wewnątrz elementu, przed jego pierwszym dzieckiem

„beforeend” Tylko wewnątrz elementu, po jego ostatnim potomku

„afterend” Po samym elemencie


17

W starej szkole JavaScript możesz to zrobić:

document.body.innerHTML = '<p id="foo">Some HTML</p>' + document.body.innerHTML;

W odpowiedzi na Twój komentarz:

[…] Interesowało mnie zadeklarowanie źródła atrybutów i zdarzeń nowego elementu, a nie innerHTMLelementu.

Musisz jednak wstrzyknąć nowy HTML do DOM; dlatego innerHTMLjest używany w starym przykładzie JavaScript. innerHTMLTego BODYelementu jest poprzedzany z nowym HTML. Tak naprawdę nie dotykamy istniejącego kodu HTML w BODY.

Przepiszę powyższy przykład, aby to wyjaśnić:

var newElement = '<p id="foo">This is some dynamically added HTML. Yay!</p>';
var bodyElement = document.body;
bodyElement.innerHTML = newElement + bodyElement.innerHTML;
// note that += cannot be used here; this would result in 'NaN'

Użycie frameworka JavaScript sprawiłoby, że kod byłby znacznie mniej rozwlekły i poprawiłby czytelność. Na przykład jQuery umożliwia wykonanie następujących czynności:

$('body').prepend('<p id="foo">Some HTML</p>');

Całkiem dobre. Interesowało mnie jednak zadeklarowanie źródła atrybutów i zdarzeń nowego elementu, a nie innerHTML elementu.
TheFlash

1
document.getElementsByTagName('body')[0]rzeczywiście można go zastąpić document.body, słuszna uwaga. Jeśli jednak chcesz dołączyć lub dołączyć nowy kod HTML do innego istniejącego elementu zamiast BODY, będziesz musiał użyć document.getElementById()i / lub document.getElementsByTagName(); dlatego użyłem go w przykładzie.
Mathias Bynens

1
Ponadto kod może stać się bardzo brudny, bardzo szybko, jeśli bezpośrednio dodajesz / wstawiasz „innerHTML”
James

1
@JimmyP: Co za bzdury! Głównym celem tego pytania jest możliwość bezpośredniego wstawiania kodu HTML jako ciągów znaków zamiast bawić się funkcjami do jego konstruowania, atrybuty według atrybutu, węzeł po węźle, element po elemencie.
TheFlash

1
powoduje to odłączenie wszystkich programów obsługi zdarzeń i może powodować duże wycieki pamięci.
adardesign

1

Według mojej wiedzy, która, szczerze mówiąc, jest dość nowa i ograniczona, jedynym potencjalnym problemem związanym z tą techniką jest to, że uniemożliwione jest dynamiczne tworzenie niektórych elementów tabeli.

Używam formularza do tworzenia szablonów, dodając elementy „szablonu” do ukrytego DIV, a następnie używając cloneNode (true), aby utworzyć klon i dołączyć go zgodnie z wymaganiami. Pamiętaj, że musisz upewnić się, że w razie potrzeby ponownie przypisujesz identyfikatory, aby zapobiec powielaniu.


-1

Jak powiedzieli inni, wygodna funkcjonalność dołączania jQuery może być emulowana:

var html = '<div>Hello prepended</div>';
document.body.innerHTML = html + document.body.innerHTML;

Chociaż niektórzy twierdzą, że lepiej nie "zadzierać" z innerHTML , jest on niezawodny w wielu przypadkach, jeśli wiesz, że:

Jeżeli <div>, <span>lub <noembed>węzeł posiada węzeł podrzędny tekstowy, który zawiera znaki ( &), ( <) lub ( >), innerHTML zwraca te znaki jak &amp, &lti &gtodpowiednio. Użyj, Node.textContentaby uzyskać poprawną kopię zawartości tych węzłów tekstowych.

https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

Lub:

var html = '<div>Hello prepended</div>';
document.body.insertAdjacentHTML('afterbegin', html)

insertAdjacentHTMLto prawdopodobnie dobra alternatywa: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML


-2

Jeśli chcesz wstawić kod HTML do znacznika istniejącej strony, użyj Jneratora . To narzędzie zostało stworzone specjalnie do tego celu.

Zamiast pisać kolejny kod

    var htmlCode = '<ul class=\'menu-countries\'><li
        class=\'item\'><img src=\'au.png\'></img><span>Australia </span></li><li
        class=\'item\'><img src=\'br.png\'> </img><span>Brazil</span></li><li
        class=\'item\'> <img src=\'ca.png\'></img><span>Canada</span></li></ul>';
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;

Możesz napisać bardziej zrozumiałą strukturę

    var jtag = $j.ul({
        class: 'menu-countries',
        child: [
            $j.li({ class: 'item', child: [
                $j.img({ src: 'au.png' }),
                $j.span({ child: 'Australia' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'br.png' }),
                $j.span({ child: 'Brazil' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'ca.png' }),
                $j.span({ child: 'Canada' })
            ]})
        ]
    });
    var htmlCode = jtag.html();
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.