如何使用 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,然后点击[<>]
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();
);
<div id="projects"></div>
【讨论】:
也许在这种情况下你是对的,这可能会让人困惑,我个人认为有一个不使用任何库的解决方案示例还不错,无论某些人在他们的项目中使用什么,它都有效,也许为此苦苦挣扎,我也认为您的回答更好,我什至赞成:)。以上是关于如何使用 JQuery 一次将多个图像添加到 DOM?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django 中一次将多个对象添加到 ManyToMany 关系?