[英]Retrieve preloaded image from cached array
我正在使用JavaScript進行多個圖像預加載,並且為每個圖像都分配了一些樣式屬性,這是可能的,因為它們是HTML Images元素。 我用的是無極的技術,我發現這里 StackOverflow上:
function preloadImages(srcs) {
function loadImage(imgToLoad) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
resolve(img);
};
img.onerror = img.onabort = function() {
reject(imgToLoad.src);
};
img.className = 'testimg'; //Test to see if I can retrieve img
img.src = imgToLoad.src;
img.style.top = imgToLoad.top;
});
}
var promises = [];
for (var i = 0; i < srcs.length; i++) {
promises.push(loadImage(srcs[i]));
}
return Promise.all(promises);
}
“ srcs”值的示例:
srcs[0].top = '15%';
srcs[0].src = 'img/myImage1.jpg';
srcs[1].top = '24%';
srcs[1].src = 'img/myImage2.jpg';
預加載部分工作完美,並且在流程結束時我能夠獲得所有預加載的圖像,看到樣式屬性已被應用,如下所示:
preloadImages(imgToLoad).then(function(imgs) {
// all images are loaded now and in the array imgs
console.log(imgs); // This works
console.log(document.getElementsByClassName('testimg')); //This doesn't
}, function(errImg) {
// at least one image failed to load
console.log('error in loading images.');
});
但是,在我的代碼后面,我想從預加載的圖像數組中提取一些元素,因此我可以追加它們而不必精確調整樣式屬性。
我的意思是,不僅限於.append('aSrcThatHasBeenPreloaded');
。 我想保留在預加載期間定義的類和樣式屬性。
那有可能嗎? 如果是這樣,我應該如何進行?
我嘗試了document.getElementsByClassName('myPreloadedClass')
但是它返回一個空結果,這意味着預加載的圖像不是DOM的一部分(這很有意義)。
謝謝您的幫助。
您將必須確保可以某種方式檢索預加載的img
元素。 有很多方法可以做到這一點,但是馬上想到了三種。
在您的示例中,您嘗試使用查詢選擇器檢索圖像。 失敗是因為img
元素未添加到DOM。 您可以將它們附加到對用戶隱藏的DOM元素上。
var images = [ { src: '//placehold.it/550x250?text=A', top: 0, class:'img-a' // unique class name to retrieve item using a query selector. }, { src: '//placehold.it/550x250?text=B', top: 0, class:'img-b' }], imageCache = document.getElementById('image-cache'); function preloadImages(srcs) { function loadImage(imgToLoad) { return new Promise(function(resolve, reject) { var img = new Image(); img.onload = function() { // The image has been loaded, add it to the cache element. imageCache.appendChild(img); resolve(img); }; img.onerror = img.onabort = function() { reject(imgToLoad.src); }; img.className = 'testimg ' + imgToLoad.class; //Test to see if I can retrieve img img.src = imgToLoad.src; img.style.top = imgToLoad.top; }); } var promises = []; for (var i = 0; i < srcs.length; i++) { promises.push(loadImage(srcs[i])); } return Promise.all(promises); } // Load all the images. preloadImages(images) .then(result => { // Add img B from the cache to the proof div. document.getElementById('proof').appendChild(imageCache.querySelector('.img-b')); });
.hidden { display: none; }
<div id="image-cache" class="hidden"></div> <div id="proof"></div>
如果您不想將img
添加到DOM中,則可以將它們添加到文檔片段中 。 這樣,網站的訪問者將無法輕松訪問它們,並且您仍然可以使用查詢選擇器來檢索圖像。
var images = [ { src: '//placehold.it/550x250?text=A', top: 0, class:'img-a' // unique class name to retrieve item using a query selector. }, { src: '//placehold.it/550x250?text=B', top: 0, class:'img-b' }], // Create a document fragment to keep the images in. imageCache = document.createDocumentFragment();; function preloadImages(srcs) { function loadImage(imgToLoad) { return new Promise(function(resolve, reject) { var img = new Image(); img.onload = function() { // The image has been loaded, add it to the cache element. imageCache.appendChild(img); resolve(img); }; img.onerror = img.onabort = function() { reject(imgToLoad.src); }; img.className = 'testimg ' + imgToLoad.class; //Test to see if I can retrieve img img.src = imgToLoad.src; img.style.top = imgToLoad.top; }); } var promises = []; for (var i = 0; i < srcs.length; i++) { promises.push(loadImage(srcs[i])); } return Promise.all(promises); } // Load all the images. preloadImages(images) .then(result => { // Add img B from the cache to the proof div. document.getElementById('proof').appendChild(imageCache.querySelector('.img-b')); // And try to add img B from the cache to the proof2 div. The image will only be visible once in the site. document.getElementById('proof2').appendChild(imageCache.querySelector('.img-b')); });
.hidden { display: none; }
<div id="proof"></div> <div id="proof2" style="margin-top:1em"></div>
第二種解決方案與第一種解決方案非常相似。 您仍然可以使用查詢選擇器來訪問圖像。 但是,這兩種解決方案都有相同的缺點,一旦您將緩存中的圖像放置在站點上的其他任何地方,您就無法再從緩存中檢索圖像。 這是因為一個元素只能在DOM中出現一次,並將其附加到另一個元素會將其從其先前的父元素中刪除。
我建議創建一個閉包或ES6類,在其中可以放置用於預加載圖像和檢索圖像的所有功能。
以下代碼段的關閉返回了兩種方法:
preloadImages
,它需要預加載圖像數組。 getImage
,它帶有一個有效的CSS選擇器,該選擇器用於從文檔片段中檢索所需的img
元素。 在返回該元素之前,它將對其進行克隆,因此您可以向DOM中多次添加相同的預加載圖像。 克隆一個元素也將克隆它的ID,這一點要注意。 我認為這不是什么大問題,因為img
是用代碼創建的,因此您可以完全控制它。
我使用文檔片段來存儲預加載的圖像,因為我認為這是比將圖像添加到DOM更優雅的解決方案。 如果不使用getImage
方法,則獲取img
元素會變得更加困難,從而防止以某種方式從圖像緩存中刪除預加載的img
元素。
var images = [ { src: '//placehold.it/550x250?text=A', top: 0, class:'img-a' // unique class name to retrieve item using a query selector. }, { src: '//placehold.it/550x250?text=B', top: 0, class:'img-b' }]; var imagesPreloader = (function() { var imagesCache = document.createDocumentFragment(); function loadImage(imgToLoad) { return new Promise(function(resolve, reject) { var img = new Image(); img.onload = function() { imagesCache.appendChild(img) resolve(); }; img.onerror = img.onabort = function() { reject(imgToLoad.src); }; img.className = 'testimg ' + imgToLoad.class ; //Test to see if I can retrieve img img.src = imgToLoad.src; img.style.top = imgToLoad.top; }); } function preloadImages(srcs) { var promises = []; for (var i = 0; i < srcs.length; i++) { promises.push(loadImage(srcs[i])); } return Promise.all(promises); } function getImage(imageSelector) { const // Find the image in the fragment imgElement = imagesCache.querySelector(imageSelector); // When the selector didn't yield an image, return null. if (imgElement === null) { return null; } // Clone the image element and return it. const resultElement = imgElement.cloneNode(); return resultElement; } return { getImage, preloadImages }; })(); imagesPreloader.preloadImages(images) .then(result => { console.log('Image with class "img-a": ', imagesPreloader.getImage('.img-a')); document.querySelector('#proof').appendChild(imagesPreloader.getImage('.img-b')); document.querySelector('#proof2').appendChild(imagesPreloader.getImage('.img-b')); });
<div id="proof"></div> <div id="proof2" style="margin-top:1em"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.