Вставка елементів 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 і в певних ситуаціях швидше, ніж у внутрішнійHTML.

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


3
Гадаю, що цей createDocumentFragment () не був би таким хорошим, як "застарілий" внутрішнійHTML.
TheFlash

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

32
crescentfresh, я допомагаю на SO, тому що мені подобається допомагати людям; Вибачте, якщо рішення не на 100% функціонує у будь-яких ситуаціях. Якщо ви так стурбовані, чому б не запропонувати власне рішення, а не зайво критикувати вже запропоновані відповіді? З будь-якою абстракцією завжди будуть крайові випадки! Це середовище навчання - ми не тут, щоб дати людям рішення на тарілці - ми тут, щоб допомогти один одному стати кращими у тому, що ми робимо! І вибачте, але де хто згадав "AJAX"?
Джеймс

1
Досить справедливо. Мої вибачення. Я просто відчуваю, що тут стільки абстракцій із згадуваними нульовими застереженнями.
Півмісяць свіжий

1
це складніше, ніж потрібно - відповідь
Сидаса

83

Ти хочеш це

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

13
не впевнений, чому це не прийнята відповідь. Це простіший і очевидно правильніший
JonnyRaa

@JonnyLeeds це, здається, не працює на bodyелементі, але добре працює на будь-якому іншому елементі.
Філ

1
@Phill Звичайно, це працює <body>. Власне кажучи, запуск його <body>- це мій стандартний метод введення таких матеріалів, як аркуші стилів, на веб-сторінки через консоль. Яке питання у вас виникає?
Šime Vidas

@ ŠimeVidas, ймовірно, тому, що елемент тіла не був визначений під час виконання ... Я спарив вашу лінію з window.onload = function () {…}, щоб запобігти цій проблемі
GDY

@Grandy Phill написав, що це працює на інших елементах. Якби їх не <body>було визначено, це було б і з усіма іншими елементами, то це, ймовірно, не проблема Філла.
Šime Vidas

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>

позиція - це положення відносно елемента, який ви вставляєте поруч із:

'перед початком ' Перед самим елементом

'afterbegin' Просто всередині елемента, перед його першою дитиною

"перед тим", що знаходиться всередині елемента, після останнього дочірнього елемента

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

Досить добре. Але мені було цікаво оголосити джерело атрибутів і подій нового елемента, а не внутрішнійHTML елемента.
TheFlash

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

1
Також ваш код може дуже швидко забруднитися, якщо ви безпосередньо додаєте / вставляєте "innerHTML"
James

1
@JimmyP: Яке сміття! Сама мета цього питання полягає в тому, щоб мати можливість безпосередньо вставляти HTML як рядки, а не грати з функціями для його побудови, attrib by attrib, node by node, element for element.
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.