简体   繁体   English

在 forEach 循环中使用 Javascript FileReader 来附加元素

[英]Using Javascript FileReader in forEach loop to append elements

I am using the FileReader to insert HTML to a preview element.我正在使用 FileReader 将 HTML 插入到预览元素中。 That parts works.那部分工作。 However I need to manipulate the elements after they are inserted.但是,我需要在插入元素后对其进行操作。 When I try to select the inserted elements with (let previews = document.querySelectorAll('.fb-preview li');) I get and empty node array.当我尝试使用 (let previews = document.querySelectorAll('.fb-preview li');) 选择插入的元素时,我得到并清空节点数组。

I was under the impression that forEach is blocking and by the time the loop finishes I should be able to select the inserted html elements.我的印象是 forEach 正在阻塞,当循环完成时,我应该能够选择插入的 html 元素。

Is there something I am missing about the FileReader or forEach loops?我对 FileReader 或 forEach 循环有什么遗漏吗?

It works if I add a setTimeout but that seems hackish.如果我添加一个 setTimeout ,它就可以工作,但这似乎很hackish。

items.forEach(v => {               
    const preview = document.querySelector('.fb-preview');
    const reader = new FileReader();

    reader.addEventListener('load', () => {
        switch (v.type) {
            case 'application/pdf':
                preview.insertAdjacentHTML('beforeend', `<li><embed src=${reader.result}></i><span>${v.name}</span></li>`);
            break;
            case 'image/jpeg':
            case 'image/tiff':
            case 'image/gif':
            case 'image/png':
                preview.insertAdjacentHTML('beforeend', `<li><img src="${reader.result}"></i><span>${v.name}</span></li>`);
            break;
            default:
                preview.insertAdjacentHTML('beforeend', `<li><i class="fas fa-question-circle fa-fw"></i><span>${v.name}</span></li>`);
            break;
        }
    }, false);

    if (v) reader.readAsDataURL(v);        
});

let previews = document.querySelectorAll('.fb-preview li'); 
if (previews.length > 10) previews.forEach(e => e.style.height = '50%');
if (previews.length > 20) previews.forEach(e => e.style.height = '30%');
if (previews.length > 30) previews.forEach(e => e.style.height = '10%');

Your code shows that the DOM mutations happen in an event listener, which is asynchronous.您的代码显示 DOM 突变发生在异步事件侦听器中。 The forEach loop only registers the listeners, it does not block while reading each files. forEach循环仅注册侦听器,在读取每个文件时不会阻塞。

There is a better and easier way to accomplish your purpose: Blob URLs.有一种更好、更简单的方法可以实现您的目的:Blob URL。 You have a FileReader, so presumably you have Files to begin with ?你有一个 FileReader,所以大概你有 Files 开始? File is a subclass of Blob, so you can use URL.createObjectURL on them. File 是 Blob 的子类,因此您可以对它们使用URL.createObjectURL That gives you, synchronously, a relatively short "blob:" URL which references (but does not represent) the file's contents.这会同步为您提供一个相对较短的“blob:” URL,该 URL 引用(但不代表)文件的内容。 Use that as the source of your images and embeds.将其用作图像和嵌入的来源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM