Подтвердить что ты не робот

Определение HTML-шаблона для добавления с помощью JQuery

У меня есть массив, который я перебираю. Каждый раз, когда условие истинно, я хочу добавить копию кода HTML ниже в контейнерный элемент с некоторыми значениями.

Где я могу поместить этот HTML-код для повторного использования интеллектуальным способом?

<a href="#" class="list-group-item">
    <div class="image">
         <img src="" />
    </div>
    <p class="list-group-item-text"></p>
</a>

JQuery

$('.search').keyup(function() {
    $('.list-items').html(null);

    $.each(items, function(index) {
        // APPENDING CODE HERE
    });
});
4b9b3361

Ответ 1

Вы можете решить использовать в своем проекте механизм шаблонов, например:

Если вы не хотите включать другую библиотеку, John Resig предлагает решение jQuery, похожее на приведенное ниже.


Браузеры и устройства чтения с экрана игнорируют непризнанные типы script:

<script id="hidden-template" type="text/x-custom-template">
    <tr>
        <td>Foo</td>
        <td>Bar</td>
    <tr>
</script>

Используя jQuery, добавление строк на основе шаблона будет напоминать:

var template = $('#hidden-template').html();

$('button.addRow').click(function() {
    $('#targetTable').append(template);
});

Ответ 2

Старый вопрос, но поскольку вопрос задает "использование jQuery", я думал, что предоставил бы вариант, который позволит вам сделать это, не введя никакой зависимости от поставщика.

Несмотря на то, что в мире много шаблонов, многие из их функций в последнее время стали разочаровываться, итерация (<% for), условные обозначения (<% if) и преобразования (<%= myString | uppercase %>), рассматриваемые как микроязык в лучшими и анти-шаблонами в худшем случае. Современные шаблонные методы поощряют просто сопоставление объекта с его представлением DOM (или другого), например. что мы видим со свойствами, сопоставленными с компонентами в ReactJS (особенно безстоящими компонентами).

Шаблоны внутри HTML

Одно свойство, на которое вы можете положиться, для хранения HTML-кода для вашего шаблона рядом с остальной частью вашего HTML, - это использование неиспользуемого <script> type, например. <script type="text/template">. Для вашего случая:

<script type="text/template" data-template="listitem">
    <a href="${url}" class="list-group-item">
        <table>
            <tr>
                <td><img src="${img}"></td>
                <td><p class="list-group-item-text">${title}</p></td>
            </tr>
        </table>
    </a>
</script>

При загрузке документа прочитайте свой шаблон и отметьте его с помощью простого String#split

var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);

Обратите внимание, что с нашим токеном вы получаете его в переменном формате [text, property, text, property]. Это позволяет нам красиво сопоставить его с помощью Array#map с функцией отображения:

function render(props) {
  return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}

Где props может выглядеть как { url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }.

Объединяя все вместе, если вы проанализировали и загрузили ваш itemTpl, как указано выше, и у вас есть массив items в области:

$('.search').keyup(function () {
  $('.list-items').append(items.map(function (item) {
    return itemTpl.map(render(item)).join('');
  }));
});

Этот подход также является всего лишь едва jQuery - вы должны использовать тот же подход, используя ванильный javascript с document.querySelector и .innerHTML.

jsfiddle

Шаблоны внутри JS

Вопрос, который вы задаете себе, - это: хотите ли вы/нужно определить шаблоны в виде файлов HTML? Вы всегда можете компоновать + повторно использовать шаблон так же, как вы бы повторно использовали большинство вещей, которые хотите повторить: с помощью функции.

В es7-land, используя деструктурирование, шаблонные строки и функции-стрелки, вы можете написать совершенно красивые компоненты компонента, которые можно легко загрузить с помощью метода $.fn.html выше.

const Item = ({ url, img, title }) => `
  <a href="${url}" class="list-group-item">
    <div class="image">
      <img src="${img}" />
    </div>
    <p class="list-group-item-text">${title}</p>
  </a>
`;

Затем вы можете легко отобразить его, даже отображаемый из массива, например:

$('.list-items').html([
  { url: '/foo', img: 'foo.png', title: 'Foo item' },
  { url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));

О и последнее замечание: не забывайте санировать ваши свойства, переданные в шаблон, если они читаются из БД, или кто-то может передать HTML (а затем запустить скрипты и т.д.) со своей страницы.

Ответ 3

Добавить где-нибудь в теле

<div class="hide">
<a href="#" class="list-group-item">
    <table>
        <tr>
            <td><img src=""></td>
            <td><p class="list-group-item-text"></p></td>
        </tr>
    </table>
</a>
</div>

затем создайте css

.hide { display: none; }

и добавьте в js

$('#output').append( $('.hide').html() );

Ответ 4

Используйте вместо этого HTML-шаблон!

Поскольку принятый ответ будет представлять собой перегрузку метода script, я хотел бы предложить другой, который, на мой взгляд, намного чище и безопаснее из-за рисков XSS, связанных с перегрузкой скриптов.

Я сделал демо, чтобы показать вам, как использовать его в действии и как вставлять один шаблон в другой, редактировать, а затем добавлять в документ DOM. https://codepen.io/DevWL/pen/YrjyWm?editors=1010

пример html

<template id="mytemplate">
  <style>
     .image{
        width: 100%;
        height: auto;
     }
  </style>
  <a href="#" class="list-group-item">
    <div class="image">
      <img src="" />
    </div>
    <p class="list-group-item-text"></p>
  </a>
</template>

пример js

// select
var t = document.querySelector('#mytemplate');

// set
t.content.querySelector('img').src = 'demo.png';
t.content.querySelector('p').textContent= 'demo text';

// add to document DOM
var clone = document.importNode(t.content, true); // where true means deep copy
document.body.appendChild(clone);

HTML &lttemplate >

  • + Его содержимое эффективно инертно до активации. По сути, ваш разметка скрыта DOM и не отображает.

  • + Любой контент в шаблоне не будет иметь побочных эффектов. Скрипты не запускаются, изображения не загружаются, звук не воспроизводится... пока не будет использован шаблон.

  • + Содержимое не считается в документе. Использование document.getElementById() или querySelector() на главной странице не будет возвращать дочерние узлы шаблона.

  • + Шаблоны могут быть размещены в любом месте <head>, <body> или <frameset> и могут содержать любой тип контента, который разрешен в этих элементах. Обратите внимание, что "где угодно" означает, что <template> можно безопасно использовать в тех местах, где не разрешен парсер HTML.

Возврат назад

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

Чтобы обнаружить функцию <template>, создайте элемент DOM и убедитесь, что существует свойство .content:

function supportsTemplate() {
  return 'content' in document.createElement('template');
}

if (supportsTemplate()) {
  // Good to go!
} else {
  // Use old templating techniques or libraries.
}

Некоторые сведения о методе перегрузки script

  • + Ничего не отображается - браузер не отображает этот блок, поскольку по умолчанию тег <script> имеет display:none.
  • + Inert - браузер не анализирует содержимое script как JS, потому что его тип имеет значение, отличное от "text/javascript".
  • - Проблемы безопасности - поощряет использование .innerHTML. Анализ времени выполнения пользовательских данных может легко привести к уязвимостям XSS.

Полная статья: https://www.html5rocks.com/en/tutorials/webcomponents/template/#toc-old

Полезная ссылка: https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode http://caniuse.com/#feat=queryselector

Ответ 5

Другая альтернатива: Pure

Я использую его, и это очень помогло мне. Пример, показанный на их веб-сайте:

HTML

<div class="who">
</div>

JSON

{
  "who": "Hello Wrrrld"
}

Результат

<div class="who">
  Hello Wrrrld
</div>

Ответ 6

Чтобы решить эту проблему, я распознаю два решения:

  • Первый идет с AJAX, с помощью которого вам придется загрузить шаблон из другого файла и просто добавлять каждый раз, когда вы хотите с .clone().

    $.get('url/to/template', function(data) {
        temp = data
        $('.search').keyup(function() {
            $('.list-items').html(null);
    
            $.each(items, function(index) {
                 $(this).append(temp.clone())
            });
    
        });
    });
    

    Учтите, что событие должно быть добавлено после завершения ajax, чтобы убедиться, что данные доступны!

  • Второй способ заключается в том, чтобы напрямую добавить его в исходный html, выбрать его и скрыть в jQuery:

    temp = $('.list_group_item').hide()
    

    После добавления нового экземпляра шаблона с помощью

    $('.search').keyup(function() {
        $('.list-items').html(null);
    
        $.each(items, function(index) {
            $(this).append(temp.clone())
        });
    });
    
  • Как и предыдущий, но если вы не хотите, чтобы шаблон оставался там, но только в javascript, я думаю, вы можете использовать (не проверял его!) .detach() вместо скрытия.

    temp = $('.list_group_item').detach()
    

    .detach() удаляет элементы из DOM, сохраняя данные и события живыми (.remove() не работает!).