【问题标题】:Attach DOM elements to other DOM elements only after they have loaded仅在加载后将 DOM 元素附加到其他 DOM 元素
【发布时间】:2020-02-18 14:20:34
【问题描述】:

我正在尝试编写代码来执行以下操作:

  1. 当用户上传图像时,将这些图像的预览作为画布元素返回。 (这由 loadImage API 处理)
  2. 在每个画布旁边附加 div 元素。

要按顺序执行上述操作,只有在画布元素完全绘制后,我才需要调用 document.querySelectorAll 方法。

这是我写的代码。我在这里尝试使用promise,但显然promise 是在调用loadImage 函数之后解决的,而不是在完全绘制canvas 元素之后。当我运行该函数时,预览将填充为画布元素,但未附加“photo_order”div 元素。

function rpu() {
  let promise = new Promise(async function(resolve, reject) {
    let filez = e.target.files;
    let files = Array.from(filez);
    files.forEach(function(file) {
      loadImage(
        file,
        function(img) {
          document.querySelector('#r_im_preview').appendChild(img);
          document.querySelector('#r_im_preview').classList.remove('hide');
        }, {
          maxWidth: 150,
          orientation: true,
          contain: true
        }
      )
    });
    resolve();
  });
  promise.then(function() {
    let k1 = document.querySelectorAll('canvas');
    let k2 = Array.from(k1);
    let k3 = '<div class="photo_order" style="cursor: pointer;"></div>'
    k2.forEach(k => {
      k.insertAdjacentHTML('afterEnd', k3);
    })
  });
}

如何修复代码以实现我想要做的事情?非常欢迎任何建议。

【问题讨论】:

  • 据我所知,主要问题是 Promise 将在 for 循环后立即解决,而不是等待图像加载。试试这个:pastebin.com/p8vLtVNK
  • 效果很好。谢谢,@Chris G !!

标签: javascript html dom promise


【解决方案1】:

我认为您需要重构代码以正确使用 Promise。像这样的:

const appendPreview = (img) => {
    document.querySelector('#r_im_preview').appendChild(img)
    document.querySelector('#r_im_preview').classList.remove('hide');
}

const loadImageP = (file, cb, settings) => new Promise((resolve, reject) => {
    try {
        const cbP = (...args) => (cb(...args), resolve)
        loadImage(file, cbP, settings)
    } catch {
        reject()
    }
})

const settings = {
    maxWidth: 150
    orientation: true,
    contain: true
}

async function rpu() {
    const promises = [...e.target.files].reduce((acc, file) => 
        [...acc, loadImageP(file, appendPreview, settings))], [])

    await Promise.all(promises)

    let canvasNodes = document.querySelectorAll('canvas');
    let orderNode = '<div class="photo_order" style="cursor: pointer;"></div>'
    [...canvasNodes].forEach((n) => { n.insertAdjacentHTML('afterEnd', orderNode);
}

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 2016-07-24
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 2018-09-23
    相关资源
    最近更新 更多