Проблема
У меня есть коллекция изображений со связанными подписями на странице. Я хочу, чтобы каждый из них имел идентичный HTML.
Обычно я копирую и вставляю HTML снова и снова для каждого элемента. Проблема в том, что если я хочу настроить HTML, я должен сделать это для всех. Это отнимает много времени, и есть риск ошибок.
Быстрое и грязное шаблонирование
Я хотел бы написать только одну копию HTML, перечислить элементы содержимого в виде простого текста, а при рендеринге страницы HTML будет автоматически повторяться для каждого элемента содержимого.
HTML
<p><img src=IMAGE-URL>
<br>
<a target='_blank' href=LINK-URL>CAPTION</a></p>
Список содержимого
IMAGE-URL, LINK-URL, CAPTION
/data/khang.jpg, https://khangssite.com, Khang Le
/data/sam.jpg, https://samssite.com, Sam Smith
/data/joy.jpg, https://joyssite.com, Joy Jones
/data/sue.jpg, https://suessite.com, Sue Sneed
/data/dog.jpg, https://dogssite.com, Brown Dog
/data/cat.jpg, https://catssite.com, Black Cat
Отдельный предмет
В идеале я мог бы поместить текстовый контент для одного элемента в любом месте страницы с каким-то идентификатором, указывающим, какой HTML-шаблон использовать (аналогично классам с CSS).
TEMPLATE=MyTemplate1, IMAGE-URL=khang.jpg, LINK-URL=https://khangssite.com, CAPTION=Khang Le
Реализация
Широко используются системы шаблонов, такие как Django и Smarty на стороне сервера, и Mustache на стороне клиента. Этот вопрос ищет простое решение шаблона с одним файлом без использования внешних библиотек.
Я хочу добиться этого без фреймворка, библиотеки и т. д. Я хотел бы поместить HTML и список содержимого в один и тот же файл .html.
Базы точно нет. Это должно быть быстро и просто настроить на странице, без установки или настройки дополнительных сервисов.
В идеале я хотел бы сделать это без javascript, но это не является строгим требованием. Если есть javascript, он не должен знать имена полей. В идеале очень коротко и просто. Пожалуйста, без jquery.






вы имеете в виду Литералы шаблонов (строки шаблонов) ?
const arrData =
[ { img: '/data/khang.jpg', link: 'https://khangssite.com', txt: 'Khang Le' }
, { img: '/data/sam.jpg', link: 'https://samssite.com', txt: 'Sam Smith' }
, { img: '/data/joy.jpg', link: 'https://joyssite.com', txt: 'Joy Jones' }
, { img: '/data/sue.jpg', link: 'https://suessite.com', txt: 'Sue Sneed' }
, { img: '/data/dog.jpg', link: 'https://dogssite.com', txt: 'Brown Dog' }
, { img: '/data/cat.jpg', link: 'https://catssite.com', txt: 'Black Cat' }
]
const myObj = document.querySelector('#my-div')
arrData.forEach(({ img, link, txt }) =>
{
myObj.innerHTML += `
<p>
<img src = "${img}">
<br>
<a target='_blank' href = "${link}">${txt}</a>
</p>`
});<div id = "my-div"></div>@johnywhy Почти это объект JavaScript (JSO), где синтаксис двойных кавычек не требуется. В JSON это обязательно, потому что документ JSON представляет собой простой текст в кодировке UTF-8, а в качестве разделителей используются двойные кавычки (за исключением числовых типов); и вам нужно использовать анализатор JSON, чтобы преобразовать этот текст в полезные данные. В JS это команда JSON.parse(), которая создает данные JSO. -- У JSO больше технических возможностей, чем у JSON, поскольку они могут содержать методы.
Существует ли JSO-эквивалент JSON.parse()?
@johnywhy JSO — это (редко используемый) акроним для объектов JavaScript, JSON — это обычное сокращение для «формат JSON» , это также JSGO (глобальный объект JS) с именем JSON (с различными методами, такими как JSON.parse() или [JSON.stringify()](JSON.stringify())). Пожалуйста, прочитайте документ и, если возможно, отметьте мой ответ как принятый.
Итак, ваш arrData уже является объектом, и его не нужно анализировать, верно?
Спасибо за этот ответ, но он не выполняет запрос на перечисление данных и имен полей в файле HTML.
я проголосовал за ваш ответ, кстати.
Этот ответ является полным решением. Очень интересно редактировать HTML-шаблон в codepen и наблюдать за изменением макета каждой копии в режиме реального времени — это похоже на опыт редактирования класса CSS и наблюдения за изменениями в реальном времени.
Вот код, за которым следует объяснение.
HTML
<span id = "template-container"></span>
<div hidden id = "template-data">
IMG,, LINK,, CAPTION
https://www.referenseo.com/wp-content/uploads/2019/03/image-attractive.jpg,, khangssite.com,, Khang Le
https://i.redd.it/jeuusd992wd41.jpg,, suessite.com,, Sue Sneed
https://picsum.photos/536/354,, catssite.com,, Black Cat
</div>
<template id = "art-template">
<span class = "art-item">
<p>
<a href = "${LINK}" target = "_blank">
<img src = "${IMG}" alt = "" />
<br>
${CAPTION}
</a>
</p>
</span>
</template>
Javascript
window.onload = function LoadTemplate() {
// get template data.
let sRawData = document.querySelector("#template-data").innerHTML.trim();
// load header and data into arrays
const headersEnd = sRawData.indexOf("\n");
const headers = sRawData.slice(0, headersEnd).split(",,");
const aRows = sRawData.slice(headersEnd).trim().split("\n");
const data = aRows.map((element) => {
return element.split(",,");
});
// grab template and container
const templateHtml = document.querySelector("template").innerHTML;
const container = document.querySelector("#template-container");
// make html for each record
data.forEach((row) => {
let workingCopy = templateHtml;
// load current record into template
headers.forEach((header, column) => {
let value = row[column].trim();
let placeholder = `\$\{${header.trim()}\}`;
workingCopy = workingCopy.replaceAll(placeholder, value);
});
// append template to page, and loop to next record
container.innerHTML += workingCopy;
});
};
Новая версия на гитхабе: https://github.com/johnaweiss/HTML-микро-шаблоны
Требование
Как указано в вопросе, это решение предназначено для оптимизации процесса кодирования на стороне HTML. В этом весь смысл любого веб-шаблона. Таким образом, JS должен работать немного усерднее, чтобы облегчить жизнь HTML-программисту.
Вопрос ищет многоразовое решение. Поэтому JS не должен знать о шаблоне, полях и списке данных. Так что, в отличие от ответа @MisterJojo, шаблон и все данные находятся в моем HTML, а не в javascript. Код JS является общим.
Дизайн
Мое решение основано на теге <template>, который предназначен именно для этого использования. Он имеет различные преимущества, например, шаблон не отображается, не обрабатывается и не проверяется браузером, поэтому он меньше влияет на производительность. Программисту не нужно писать явный display:none стиль.
https://news.ycombinator.com/item?id=33089975
Однако теги <template> обычно предназначены только для загрузки контента в макет. Это неадекватно. Этот инструмент позволяет использовать переменные шаблона в любом месте HTML, в том числе внутри тегов (например, таких атрибутов, как <img src).
HTML
Мой HTML состоит из трех блоков:
<template><span> со СКРЫТЫМ атрибутом.<span>.Шаблон
Мой образец шаблона включает 3 заполнителя для данных:
${LINK}
${IMG}
${CAPTION}
Но, конечно, вы можете использовать любые заполнители, любое их количество. Я использую стиль разделителя строковых литералов (хотя на самом деле я не использую их как строковые литералы — я просто позаимствовал стиль разделителя).
Элемент данных
Вопрос указывает, что данные должны храниться в HTML. Это должно требовать минимальных нажатий клавиш.
hidden. CSS не нужен.ЯВАСКРИПТ
Данные
Данные обрабатываются Javascript с двумя операторами разделения, сначала на разделителе новой строки, затем на разделителе с двойной запятой. Это помещает все это в 2D-массив. Мой JS использует обрезки, чтобы избавиться от лишних пробелов по мере необходимости.
Замена заполнителя
Обработка нескольких записей требует включения каждой записи в шаблон.
я использовал простую замену строк вместо строковых литералов.
Несколько шаблонов
Новая версия, которая поддерживает несколько шаблонов и возможность использовать один и тот же шаблон в нескольких местах на одной странице.
https://github.com/johnaweiss/HTML-микро-шаблоны
Будущее
Вдохновленный @MisterJojo, более ранняя версия моего решения использовала литералы шаблонов для замены. Однако это было немного сложнее и многословнее и, казалось, требовало использования eval. Поэтому я перешел на .replaceAll. Тем не менее, шаблонные литералы кажутся более подходящим методом для шаблонов, поэтому, возможно, я вернусь к этому.
Будущая версия может адаптироваться к любому пользовательскому разделителю полей, который разработчик HTML использует для блока данных.
Разделитель в виде доллара для заполнителей немного неудобен для ввода. Поэтому я заинтересован в поиске менее неудобного разделителя без альфа-канала, который не будет конфликтовать с HTML. Учитывая двойные скобки или фигурные скобки [[NAME]]
Возможно, есть более простые способы вытащить таблицу данных в JS.
Я читал, что компоненты хорошо работают с <template>, но я туда не заходил.
Имо, комитет JS должен разработать функцию переменных-заполнителей для тегов <template> и изначально обеспечить хранение данных в HTML. Было бы здорово, если бы что-то вроде этого решения было частью движка рендеринга.
Красивый! Является ли arrData JSON? Спасибо!