【问题标题】:How to check if image loads and set it as background-image of a cloned template如何检查图像是否加载并将其设置为克隆模板的背景图像
【发布时间】:2021-12-26 13:54:55
【问题描述】:

我有一个 HTML 模板 我正在调用一些 API 并收到一个对象列表

我在所有对象上循环运行,并为每个对象创建一个模板的克隆:

const data = [{
  id: 'someid',
  poster: 'some_image_url',
  url: 'some_link_url',
  title: 'Title',
  description: 'description'
}]
const construct = data => {
  const template = document.querySelector('#type1')
  const clone = template.content.cloneNode(true)
  clone.querySelector('a').setAttribute('href', data.url)
  clone.querySelector('.poster').setAttribute('style', `background-image: url("${data.poster}")`)
  clone.querySelector('.title').textContent = data.title
  clone.querySelector('.description').textContent = data.description
  return clone
}
data.forEach(data => document.body.appendChild(construct(data)))
<template id="type1">
  <div class='type1'>
    <a>
      <div class='poster'></div>
      <div class='content'>
        <div class='title'></div>
        <div class='description'></div>
      </div>
    </a>
  </div>
</template>

到目前为止,一切正常。当我决定检查poster 链接中的图像是否已加载时,问题就开始了,如果没有,请设置一些默认图像。首先,我尝试执行以下操作(而不是 clone.querySelector('.poster')):

const img = new Image
img.onload = function() {
  clone.querySelector('.poster').setAttribute('style', `background-image: url("${data.poster}")`)
}
img.onerror = function() {
  clone.querySelector('.poster').setAttribute('style', 'background-image: url("./assets/default.png")')
}
img.src = data.poster

我收到以下错误:clone.querySelector(...) is null

我尝试使用闭包:

img.onload = (function (clone) {
  return function () {
    clone.querySelector('.poster').setAttribute('style', `background-image: url("${data.poster}")`)
  }
})(clone)
img.onerror = (function (clone) {
  return function () {
    clone.querySelector('.poster').setAttribute('style', 'background-image: url("./assets/default.png")')
  }
})(clone)

唉,同样的结果,同样的错误。

我还尝试在上述方法中使用.apply(clone),但是在这种情况下,所有图像都在onerror 方法中设置为默认图像,即使data.poster 中的URL 确实返回了图像。

为什么会发生这种情况以及如何使其发挥作用?

【问题讨论】:

  • 那么克隆你期望它在 onload 回调中是什么? querySelector 元素怎么样? sonstruct () 被调用后是否有任何修改?如果您提供一个证明此错误的minimal reproducible example 将会有所帮助
  • 我给你做了一个sn-p。
  • @charlietfl 不,克隆返回后,我将其附加到片段并将片段附加到元素。我将尝试创建一些示例。我做了一个类型,方法的名字当然是construct。编辑帖子以修复它。
  • @mplungjan 谢谢!从来不知道如何创建那些......
  • 在编辑器工具栏中点击&lt;&gt;创建sn-p

标签: javascript templates


【解决方案1】:

在异步加载事件处理程序之前保存海报元素。 在加载图像时,克隆元素似乎超出范围

const data = [{
  id: 'someid',
  poster: 'https://www.freecodecamp.org/news/content/images/2021/06/w-qjCHPZbeXCQ-unsplash.jpg',
  url: 'some_link_url',
  title: 'Title',
  description: 'description'
}]
const construct = data => {
  const template = document.querySelector('#type1')
  const clone = template.content.cloneNode(true)
  const poster = clone.querySelector('.poster')
  const img = new Image()
  
  img.onload = function() { 
    poster.setAttribute('style', `background-image: url("${data.poster}")`)
    console.log(poster.style.backgroundImage)
  }
  img.onerror = function() {
    poster.setAttribute('style', 'background-image: url("./assets/default.png")')
  }
  img.src = data.poster

  clone.querySelector('a').setAttribute('href', data.url)
  clone.querySelector('.title').textContent = data.title
  clone.querySelector('.description').textContent = data.description
  return clone
}
data.forEach(data => document.body.appendChild(construct(data)))
.poster { height: 100px; width: 100px ; }
<template id="type1">
  <div class='type1'>
    <a>
      <div class='poster'></div>
      <div class='content'>
        <div class='title'></div>
        <div class='description'></div>
      </div>
    </a>
  </div>
</template>

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2016-09-10
    相关资源
    最近更新 更多