如何使用 JQuery 一次将多个图像添加到 DOM?

Posted

技术标签:

【中文标题】如何使用 JQuery 一次将多个图像添加到 DOM?【英文标题】:How to add multiple images to the DOM all at once with JQuery? 【发布时间】:2021-10-22 05:58:44 【问题描述】:

我正在为从带有each 循环的数组接收的多个图像创建一个创建img 元素,但我想一次将它们全部插入到DOM,但它们一次添加一个,换句话说,我想等到所有的元素都被创建后才显示在 DOM 上。

我创建了这个逻辑,希望我能实现我想要的。

    const projectData = [
      coverImg: '../someImg-1.png,
      coverImg: '../someImg-2.png,
      coverImg: '../someImg-3.png,
      coverImg: '../someImg-4.png,
   ]



$(function() 
  let imagesArr = []

  const projects_container = $('<div></div>')
  projects_container.addClass('projects_container')

  $.each(projectData, (index, value) => 
    const card_block_El = $('<div></div>')
    card_block_El.appendTo(projects_container)

    const card_img_div_El = $('<div></div>')
    const card_img_El = $('<img>')
    card_img_El.attr('src', value.coverImg)
    card_img_El.appendTo(card_img_div_El)

    card_img_div_El.appendTo(card_block_El)

    imagesArr.push(card_block_El)
  )

  if (imagesArr.length >= projetosData.length) 
    projects_container.appendTo('#projects')
  
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="projects"></div>

我的想法是,元素将在循环内一次创建并附加到projects_container,但在循环之后,因为所有图像都已附加到其容器中(由有条件的),当我将容器附加到projects 时,它们将一次全部加载,但这不是正在发生的事情,图像被一次插入到 DOM 中,即使它们已经创建。我刚开始学习 JQuery,我相信我没有做对。

我怎样才能做到这一点?

附:我正在从 Firebase Firestore 获取图像到 projectData 文件并将其导入到此脚本中。

【问题讨论】:

请点击edit,然后点击[&lt;&gt;] sn-p 编辑器并将导入替换为示例数据 看起来你的代码应该已经做你想做的事了。是什么让您认为元素一次插入到 DOM 中? @Ouroborus 好吧,我可以看到它。当我运行现场演示时,图像就像:第一个 img...第二个 img...第三个 img...等等。它们不是作为一组 imgs 立即插入的。 图像一次加载一个,也许这就是您所看到的。如果您希望一次显示所有图像,请预加载它们,并仅在所有图像完成加载后为其插入 html 这能回答你的问题吗? Preload images and insert into DOM 【参考方案1】:

你正在寻找这个

我把容器藏起来了 我一次性预加载和附加 HTML 加载最后一张图片后,我会显示容器

const projectData = [
 coverImg: 'https://via.placeholder.com/350x150?text=image1' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image2' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image3' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image4' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image5' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image6' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image7' , 
 coverImg: 'https://via.placeholder.com/350x150?text=image8'  
]

$(function() 
  const $projects_container = $("#projects");
  let counter = 0
  $projects_container.addClass('projects_container')
  $projects_container.html(projectData.map((value, i) =>     
    let img = new Image;
    $(img).on("load",() => 
      counter++;
      if (counter===projectData.length) 
        $('#projects').fadeIn("slow")
        
    )
    img.src=value.coverImg;
    const html = `<div class="card_block">
           <div class="card_img_div_El">Image $i+1<br/>
             <img class="card_img_El" src="$img.src"/>
           </div>
         </div>`;
    return html
  ).join(''));
  const $images = $("#projects").find('.card_img_El');
  
)
#projects  display: none;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="projects"></div>

【讨论】:

我会试试的。 虽然我同意这是一种更好的方法,但这实际上并不能回答 OP 的问题。他们已经在使用容器元素,将所有内容插入该容器,然后将该容器插入到文档中。虽然速度较慢,但​​它会产生相同的效果。 OP 的问题是:为什么看起来元素被一个一个地直接插入到文档中? 如果您添加代码以预加载图像(例如,new Image()),这将回答问题。事实上,它是相同的代码,经过简化。 @Berg_Durden 在技术意义上,是的。如果在演示方面,您希望用户看到延迟,然后所有内容同时弹出,您需要预加载图像。然后,当它们都加载完毕并准备就绪时,填充 DOM。如何预加载在 *** 的其他地方进行了彻底的讨论,因此在这个问题中提问会使其重复。您的问题的 cmets 中链接了一种可能性。 @Berg_Durden 对不起,我被打断了。我已修正错别字并正在预加载图片【参考方案2】:

你可以等到每张图片都加载完毕,我会用 settimeout 来做。

const projectData = [
     coverImg: 'https://via.placeholder.com/350x150?text=image1' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image2' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image3' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image4' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image5' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image6' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image7' ,
     coverImg: 'https://via.placeholder.com/350x150?text=image8' 
];


document.addEventListener("DOMContentLoaded", function(event) 
    
    const projects_container = document.createElement("div");
    projects_container.classList.add('projects_container');
    for(i=0;i<projectData.length;i++)
    
        const card_block_El   = document.createElement("div");
        const card_img_div_El = document.createElement("div");
        const card_img_El     = document.createElement("img");
        card_img_El.src       = projectData[i].coverImg;

        card_img_div_El.appendChild(card_img_El);
        card_block_El.appendChild(card_img_div_El);
        projects_container.appendChild(card_block_El);
    


   document.getElementById("projects").style.display = "none";
   document.getElementById("projects").appendChild(projects_container)  ;


    var CheckImages=function () 
        var loadedimages=0;
        var images=document.getElementById("projects").getElementsByTagName("img");
        for(i=0;i<images.length;i++)
            if(images[i].complete && images[i].naturalHeight !== 0)
                loadedimages++;
            

        
        if(images.length ==loadedimages)
        
            document.getElementById("projects").style.display = "block";
        
        else
        
            setTimeout(CheckImages, 1000);
        
    
    CheckImages();
  );
&lt;div id="projects"&gt;&lt;/div&gt;

【讨论】:

也许在这种情况下你是对的,这可能会让人困惑,我个人认为有一个不使用任何库的解决方案示例还不错,无论某些人在他们的项目中使用什么,它都有效,也许为此苦苦挣扎,我也认为您的回答更好,我什至赞成:)。

以上是关于如何使用 JQuery 一次将多个图像添加到 DOM?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中一次将多个对象添加到 ManyToMany 关系?

一次将多个图像上传到 Firebase

如何一次将一个项目添加(推送)到一个数组(循环遍历数组)

如何使用 Codeigniter 3 一次将图像输入到 2 个表中

一次将多个操作添加到核心 - 数据关系

使用php一次将多个项目提交到贝宝购物车