Как включить элементы HTML в документ

Можно ли включить один элемент HTML в несколько мест документа, как это делается в MediaWiki? Я хочу включать элементы внутри других элементов, не копируя и не вставляя их содержимое. Я знаю, что можно встраивать веб-страницы в другие веб-страницы с помощью фреймов, но есть ли надежный способ встраивания элементов HTML в другие элементы HTML на той же странице?

<p id = "p1">This is paragraph 1. </p>
<p id = "p2">
    This is paragraph 2.
    </p>
<p id = "p3">This is paragraph 3. It should contain paragraphs 1 and 2.
    <!-- {{p1}} {{p2}} -->
</p>

person Anderson Green    schedule 23.03.2013    source источник
comment
Для этого вам, вероятно, понадобится использовать JavaScript.   -  person Daniel Imms    schedule 23.03.2013
comment
@Tyriar Я добавил к этому вопросу тег JavaScript. Спасибо что подметил это. :)   -  person Anderson Green    schedule 23.03.2013
comment
Предполагая, что этот код работает, что должно произойти с атрибутом id дублированных абзацев? Они не должны оставаться прежними... должны ли они быть удалены или изменены?   -  person Dagg Nabbit    schedule 23.03.2013
comment
@GGG Их следует удалить, а не оставлять там. (Возможно, было бы лучше использовать атрибут class вместо атрибута id, чтобы ничего не нужно было удалять.)   -  person Anderson Green    schedule 23.03.2013
comment
@AndersonGreen, звучит разумно. Вы предпочитаете писать это в HTML-комментарии или вам подойдет что-то вроде <script>transclude("p1")</script>?   -  person Dagg Nabbit    schedule 23.03.2013
comment
@GGG Что-то вроде <script>transclude("p1")</script> может сработать.   -  person Anderson Green    schedule 23.03.2013
comment
Обратите внимание, что в HTML5 это обычно делается с помощью JS и элемент ‹template›.   -  person Mike 'Pomax' Kamermans    schedule 09.08.2020


Ответы (3)


Это немного хак, но он работает в Firefox, Chrome и Opera. Не тестировался в IE, нет его на этом ноутбуке... дайте мне знать, работает ли он в IE, если у вас будет возможность протестировать.

Поместите это в документ head, в тег script:

function transclude(elementId) {
    var clone = document.getElementById(elementId).cloneNode(true),
        placeholder;
    clone.id = null;
    document.write('<br id="__placeholder__">');
    placeholder = document.getElementById('__placeholder__');
    placeholder.parentNode.insertBefore(clone, placeholder);
    placeholder.parentNode.removeChild(placeholder);
    return transclude;
}

Чтобы включить элементы, используйте это:

<p id="p1">This is paragraph 1. </p>
<p id="p2">
    This is paragraph 2.
</p>
<p id="p3">This is paragraph 3. It should contain paragraphs 1 and 2.
    <script>transclude("p1")("p2")</script>
</p>

Примечания:

  • Атрибут ID удаляется из клонированных элементов.

  • Элементы включаются, как только запускается скрипт, содержащий вызов transclude, не дожидаясь загрузки документа. Из-за использования document.write это не будет работать после загрузки документа.

  • Мы используем фиктивный элемент-заполнитель, <br>, чтобы предотвратить побочный эффект document.write, когда запись, например, <p> после <p>, который был открыт, но не завершен, приводит к преждевременному завершению первого тега.

    Другими словами, имя тега элемента-заполнителя должно отличаться от имен любых незавершенных внешних тегов, то есть самозавершающегося тега <br>.

  • Функция включения возвращает себя для цепочки.

http://jsfiddle.net/bcWjE/1

person Dagg Nabbit    schedule 23.03.2013
comment
Обратите внимание, что это был разумный ответ в 2013 году, но в 2020 году (и далее) вы никогда не должны использовать document.write. В этом случае вы должны использовать некоторый JS, который вы загружаете с помощью <script src="transclude.js" async defer> (async, чтобы загрузить его независимо, defer, чтобы выполнить его после анализа DOM, но до передачи управления пользователю), который ищет маркеры включения (например, все, что это {{ ... }} или {% transclude ... %} или что-то в этом роде) и глубоко клонирует узлы с соответствующими атрибутами id. - person Mike 'Pomax' Kamermans; 09.08.2020

Использование jQuery:

$(document).ready(function(){
  $('#p3').html($('#p1').html()+$('#p2').html())
});

JsFiddle

person mutil    schedule 23.03.2013
comment
Это создает два элемента с одинаковым атрибутом id. Также я не верю, что OP нигде не упоминал jQuery. - person Dagg Nabbit; 23.03.2013

Возможно, более целесообразно использовать метод jQuery .clone(), который выполняет глубокое копирование DOM. узел, сохраняющий такие вещи, как связанные методы.

Тривиальный пример (из документов) применения $('.hello').clone().appendTo('.goodbye'); к

<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">Goodbye</div>
</div>

приводит к

<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">
    Goodbye
    <div class="hello">Hello</div>
  </div>
</div>
person msanford    schedule 23.03.2013
comment
Я могу жить с отрицательными отзывами, но добавьте комментарий: отрицательный отзыв без комментариев не выполняет никакой полезной функции для отвечающего или ОП. - person msanford; 04.11.2013