Вставка HTML-элементов с помощью JavaScript


105

Вместо утомительного поиска обходных путей для каждого типа атрибута и события при использовании следующего синтаксиса:

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

Есть ли способ просто объявить весь HTML-элемент в виде строки? лайк:

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

Ответы:


124

Вместо того, чтобы напрямую возиться с innerHTMLним, может быть лучше создать фрагмент, а затем вставить его:

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]);

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

  1. Вы можете использовать собственные методы DOM для вставки, такие как insertBefore, appendChild и т. Д.
  2. У вас есть доступ к фактическим узлам DOM до их вставки; вы можете получить доступ к объекту childNodes фрагмента.
  3. Использование фрагментов документа происходит очень быстро; быстрее, чем создание элементов вне DOM, и в определенных ситуациях быстрее, чем innerHTML.

Несмотря на то, что innerHTMLон используется внутри функции, все это происходит за пределами DOM, поэтому это намного быстрее, чем вы думаете ...


3
Бьюсь об заклад, этот createDocumentFragment () не так хорош, как «устаревший» innerHTML.
TheFlash

2
Этот метод работает во всех современных браузерах. Для IE 5.5 и ниже вы можете выполнить проверку, например :: if (document.createDocumentFragment) {create ('...'); } else {/ * Возможно, используйте innerHTML * /}
Джеймс,

32
crescentfresh, я помогаю на SO, потому что мне нравится помогать людям; Прошу прощения, если решение не работает на 100% во всех ситуациях. Если вы так обеспокоены, почему бы не предложить собственное решение вместо того, чтобы излишне критиковать уже предложенные ответы? В любой абстракции всегда будут крайние случаи! Это среда обучения - мы здесь не для того, чтобы предлагать людям решение на тарелке - мы здесь, чтобы помогать друг другу стать лучше в том, что мы делаем! И простите, но где кто-то упомянул "AJAX"?
Джеймс

1
Справедливо. Мои извинения. Я просто чувствую, что здесь так много абстракций без каких-либо оговорок.
Crescent Fresh

1
это намного сложнее, чем должно быть - ответ sime vidas намного лучше
sime JonnyRaa

83

Вы хотите это

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

13
не уверен, почему это не принятый ответ. Это намного проще и очевидно правильнее
JonnyRaa

@JonnyLeeds, похоже, это не работает с bodyэлементом, но отлично работает с любым другим элементом.
Фил

1
@Phill Конечно, работает <body>. Собственно говоря, его запуск - это <body>мой стандартный метод внедрения таких вещей, как таблицы стилей, в веб-страницы через консоль. Какая у вас проблема?
Шиме Видас,

@ ŠimeVidas, вероятно, потому, что элемент body не был определен во время выполнения ... я объединил вашу строку с window.onload = function () {…}, чтобы предотвратить эту проблему
GDY

@Grandy Phill написал, что он работает с другими элементами. Если бы они <body>были undefined, то были бы все остальные элементы, так что это, скорее всего, не проблема Филла.
Шиме Видас

32

Взгляните на 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>

position - это позиция относительно элемента, который вы вставляете рядом с:

'beforebegin' Перед самим элементом

'afterbegin' Внутри элемента, перед его первым потомком

'beforeend' Внутри элемента, после его последнего дочернего элемента

'afterend' После самого элемента


17

В старом JavaScript вы могли сделать это:

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

В ответ на ваш комментарий:

[...] Меня интересовало объявление источника атрибутов и событий нового элемента, а не самого innerHTMLэлемента.

Однако вам нужно вставить новый HTML в DOM; вот почему innerHTMLиспользуется в старом примере JavaScript. innerHTMLИз BODYэлемента предваряется с новым HTML. На самом деле мы не затрагиваем существующий HTML внутриBODY .

Я перепишу вышеупомянутый пример, чтобы прояснить это:

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'

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

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

Довольно хорошо. Но меня интересовало объявление источника атрибутов и событий нового элемента, а не innerHTML элемента.
TheFlash,

1
document.getElementsByTagName('body')[0]действительно может быть заменен на document.body, хороший момент. Однако, если вы хотите добавить или добавить новый HTML к другому существующему элементу вместо BODY, вам придется использовать document.getElementById()и / или document.getElementsByTagName(); поэтому я использовал его в примере.
Матиас Байненс

1
Кроме того, ваш код может очень быстро запутаться, если вы напрямую добавляете / вставляете «innerHTML»
Джеймс

1
@JimmyP: Что за чушь! Сама цель этого вопроса - иметь возможность напрямую вставлять HTML в виде строк, вместо того, чтобы играть с функциями для его создания, атрибут за атрибутом, узел за узлом, элемент за элементом.
TheFlash

1
это отключает все обработчики событий и может вызвать большие утечки памяти.
adardesign

1

Насколько мне известно, что, честно говоря, является довольно новым и ограниченным, единственная потенциальная проблема с этим методом заключается в том, что вам не позволяют динамически создавать некоторые элементы таблицы.

Я использую форму для создания шаблонов, добавляя элементы «шаблона» к скрытому DIV, а затем использую cloneNode (true) для создания клона и добавляя его по мере необходимости. Имейте в виду, что вам нужно убедиться, что вы переназначаете идентификаторы по мере необходимости, чтобы предотвратить дублирование.


-1

Как говорили другие, можно эмулировать удобную функцию добавления jQuery :

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

Хотя некоторые говорят, что с innerHTML лучше не «связываться» , во многих случаях он надежен, если вы знаете следующее:

Если узел <div>, <span>или <noembed>имеет дочерний текстовый узел, содержащий символы ( &), ( <) или ( >), innerHTML возвращает эти символы как &amp, &ltи &gtсоответственно. Используйте, Node.textContentчтобы получить правильную копию содержимого этих текстовых узлов.

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

Или:

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

insertAdjacentHTMLвероятно, хорошая альтернатива: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML


-2

Если вы хотите вставить HTML-код в тег существующей страницы, используйте Jnerator . Этот инструмент был создан специально для этой цели.

Вместо написания следующего кода

    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;

Можно написать более понятную структуру

    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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.