【问题标题】:Most efficient way to create a div with several children创建具有多个孩子的 div 的最有效方法
【发布时间】:2021-12-27 07:19:46
【问题描述】:

我正在尝试创建一个函数,该函数接受一个带有几个参数的对象并返回一个新创建的 div。

据我所知,似乎有两种主要方法可以做到这一点:

  • 自行创建每个元素并附加它
  • 创建模板字面量并设置 div 的 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
}

提前谢谢你!

【问题讨论】:

  • 您使用createElement 的第一个示例虽然更详细,但如果输入数据来自用户,则更适合尤其是
  • 最大的担忧显然是XSS。无论谁生成内容,我都强烈建议进行消毒。不是今天,不是明天,但有一天新开发人员会查看代码并说hey, why not pass a script to show that alert product team wants,然后一切都转到 sh1t。
  • 抱歉,这里有一个错字:它不是用户生成的。
  • 另一种方法是使用template,然后替换必要的值。

标签: javascript html createelement template-literals


【解决方案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 之前对其进行清理。使用正则表达式进行某种简单的验证就足以进行验证。对于消毒,您可以选择许多库之一,例如 https://www.npmjs.com/package/sanitize-html

关于性能,在您进行多次迭代之前,我不会太认真。据我所知,这是一次函数调用。所以我会选择更简洁的方式:模板字符串。但是如果你好奇的话,模板字符串是最快的。第一种方法几乎慢了 100%。你可以在这里https://jsbench.me/7gkw1t31rs/2查看我进行了 100 多次迭代的测试结果。

请记住,一旦 createDiv 函数返回其值,我告诉您的方法将需要一个 innerHTML。

【讨论】:

  • 太棒了,谢谢!当页面上有很多元素时,可以多次调用该函数。但这似乎是要走的路!我绝对需要为自己学习对代码进行基准测试,jsbench.me 看起来是一个很棒的资源!
  • 我很高兴能帮到你。 JSBench 是了解哪个是最快实现的最快方法。但是您必须始终考虑清洁代码,因此您的代码需要易于理解和清晰。下次见!
  • 快速更新:我已将 div 的创建添加到模板字面量函数中,只是为了使基准测试更公平。使用额外的 document.createElement,第二个函数实际上慢了大约 20%。不过,我仍然可以保留模板文字函数,因为它更具可读性和简洁性。
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多