#javascript #html #createelement #template-literals
Вопрос:
Я пытаюсь создать функцию, которая принимает объект с несколькими параметрами и возвращает вновь созданный div.
Из того, что я вижу, кажется, есть два основных способа добиться этого:
- создание каждого отдельного элемента и его добавление
- создаем литерал шаблона и устанавливаем divs innerHTML
входные данные функций не генерируются пользователем, поэтому я не думаю, что использование литералов шаблонов создаст проблему безопасности (пожалуйста, просветите меня, если я ошибаюсь)
Итак, теперь мои вопросы следующие:
- является ли один более эффективным, чем другой?
- какой из них предпочтительнее?
- есть ли какие-либо другие проблемы?
- есть ли еще более эффективный / лучший способ?
ниже вы можете увидеть два решения, которые я придумал.
function createDiv (entry) {
const div = document.createElement('div')
div.classList.add('exchange')
div.id = entry.exchange
const img = document.createElement('img')
img.src = `/static/img/${entry.img}.png`
img.alt = entry.name
img.classList.add('logo-image')
div.appendChild(img)
const link = document.createElement('a')
link.href = entry.url
link.classList.add('name')
link.innerText = entry.name
div.appendChild(link)
const routing = document.createElement('span')
routing.innerText = entry.routing ? entry.routing : ''
div.appendChild(routing)
const price = document.createElement('span')
price.innerText = entry.price
price.classList.add('price')
div.appendChild(price)
return div
}
function createDiv (entry) {
const div = document.createElement('div')
div.classList.add('exchange')
div.id = entry.exchange
let text = `
<img class="logo-image" src="/static/img/${entry.img}.png" alt="${entry.name}">
<a class="exchange-name" href="${entry.url}">${entry.name}</a>
<span>${routing.innerText = entry.routing ? entry.routing : ''}</span>
<span class="price">${entry.price}</span>
`
div.innerHTML = text
return div
}
Заранее благодарю вас!
Комментарии:
1. Ваш первый пример использования
createElement
, хотя и более подробный, предпочтительнее, особенно если входные данные поступают от пользователя.2. очевидно, что наибольшая проблема была
XSS
бы. Я бы настоятельно рекомендовал дезинфицировать независимо от того, кто генерирует контент. не сегодня, не завтра, но когда-нибудь новый разработчик посмотрит на код и скажетhey, why not pass a script to show that alert product team wants
, и все пойдет к sh1t.3. Извините, там была опечатка: она не сгенерирована пользователем.
4. Другим подходом может быть использование шаблона , а затем замена необходимых значений.
Ответ №1:
Как насчет того, чтобы сделать что-то вроде следующего?
const createDiv = ({ exchange, img, name, url, routing: entryRouting, price }) => {
return `
<div class="exchange" id="${exchange}">
<img class="logo-image" src="/static/img/${img}.png" alt="${name}">
<a class="exchange-name" href="${url}">${name}</a>
<span>${routing.innerText = entryRouting || ''}</span>
<span class="price">${price}</span>
</div>
`;
}
В этом случае вы получаете полную мощность литералов шаблона и уничтожения объекта.
Что касается значений, вы должны каким-то образом проверить их перед сохранением в базе данных и очистить HTML-код перед его возвратом. Для проверки может быть достаточно какой-то простой проверки с помощью регулярных выражений. Для очистки вы можете выбрать одну из многих библиотек, подобных this https://www.npmjs.com/package/sanitize-html .
Что касается производительности, я бы не стал воспринимать это слишком серьезно, пока вы не выполните много итераций. Насколько я вижу, это одноразовый вызов функции. Поэтому я бы выбрал более чистый способ: строки шаблонов. Но если вам интересно, строка шаблона является самой быстрой. Первый подход почти на 100% медленнее. Вы можете проверить результаты теста, который я провел более 100 итераций здесь https://jsbench.me/7gkw1t31rs/2 .
Помните, что подход, о котором я вам рассказываю, потребует innerHTML, как только функция createDiv вернет свое значение.
Комментарии:
1. Потрясающе, спасибо! Функция может вызываться довольно много раз, когда на странице много элементов. Но, похоже, это правильный путь! Мне определенно нужно научиться тестировать код для себя, jsbench.me похоже, это потрясающий ресурс!
2. Я рад, что помог вам с этим. JSBench — это самый быстрый способ понять, какая реализация является самой быстрой. Но вы всегда должны думать и о чистом коде, поэтому ваш код должен быть понятным и понятным. Увидимся в следующий раз!
3. Быстрое обновление: я добавил создание div в литеральную функцию шаблона, просто чтобы сделать тест более справедливым. С дополнительным document.createElement вторая функция на самом деле примерно на 20% медленнее. Я все же мог бы сохранить буквальную функцию шаблона, поскольку она намного более удобочитаема и лаконична.