[英]Waiting for image to load in JavaScript
我正在進行 Ajax 調用,它會返回一些信息,包括圖像路徑。
我在我的 HTML 中准備了所有這些信息,這些信息將顯示為一種彈出窗口。 我只是將彈出 div 的可見性從隱藏切換到可見。
要設置彈出 div 的位置,我必須根據圖像的高度進行計算。 因此,在設置位置並將可見性切換為可見之前,我必須等待圖像加載以了解其尺寸。
我嘗試了遞歸,setTimeout,完整的img屬性,while循環的技巧......但沒有成功。
那么,我該怎么做呢? 也許我應該在我的 Ajax 調用中返回尺寸。
var img = new Image();
img.onload = function() { alert("Height: " + this.height); }
img.src = "http://path/to/image.jpg";
請注意,按上述順序執行此操作很重要:首先附加處理程序,然后設置src
。 如果您以相反的方式執行此操作,並且圖像在緩存中,您可能會錯過該事件。 JavaScript 在瀏覽器中的單線程上運行(除非您使用網絡工作者),但瀏覽器不是單線程的。 瀏覽器看到src
,識別資源可用,加載它,觸發事件,查看元素以查看它是否有任何需要排隊等待回調的處理程序,沒有看到任何處理程序,並完成事件處理,都在src
行和附加處理程序的行之間。 (如果它們被注冊,回調將不會在行之間發生,它們會在隊列中等待,但如果沒有,則事件不需要等待。)
如果你使用 jQuery,你可以使用它的load事件。
看看這個例子:
$('img.userIcon').load(function(){
if($(this).height() > 100) {
$(this).addClass('bigImg');
}
});
接受的答案已過時,但確實顯示了基本的Image#onload
回調方法。 如今,您可能希望承諾圖像加載以避免回調地獄。
這個答案很好地說明了圖像加載處理程序,但正如我的評論所指出的那樣,它缺少一些關鍵點。
這是Image
的另一個更通用的承諾。 在onerror
處理程序中拒絕並將實際的圖像對象傳遞給解析器對於使函數具有最小的可重用性很重要。
改進可能包括其他參數(例如crossOrigin
)。 settings
對象或提供Image
作為參數是另一種泛化函數的方法(設置src
會觸發請求,因此應該在添加處理程序后最后執行)。
const loadImage = src => new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }) ; loadImage("http://placekitten.com/90/100").then(image => console.log(image, `\nloaded? ${image.complete}`) );
通過上述功能, Promise.all
可用於並行加載一批圖像(如果您想在某些圖像未加載的情況下繼續運行, Promise.allSettled
很有用)。
const loadImage = src => new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }) ; const imageUrls = [ "http://placekitten.com/85/150", "http://placekitten.com/85/130", "http://placekitten.com/85/110", ]; Promise.all(imageUrls.map(loadImage)).then(images => { const canvas = document.createElement("canvas"); document.body.appendChild(canvas); const ctx = canvas.getContext("2d"); images.forEach((image, i) => ctx.drawImage(image, i * 90, 0, image.width, image.height) ); });
只需將您的圖像 onload 包裝在一個帶有 promise 的函數中,然后使用 await 調用它。
async drawImg(ctx, image){
return new Promise(resolve => {
image.onload = function () {
ctx.drawImage(image, 10, 10, 200, 180);
resolve('resolved');
}
});
}
它應該可以正常工作
窗口加載事件怎么樣?
window.addEventListener('load', (event) => {
//do stuff with images
});
或者
window.onload = (event) => {
//do stuff with images
};
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
這對我有用,我需要瀏覽器在運行布局腳本之前計算圖像的大小。
function waitForImage(imgElem) { return new Promise(res => { if (imgElem.complete) { return res(); } imgElem.onload = () => res(); imgElem.onerror = () => res(); }); } // test (async () => { const img = document.querySelector('img'); // to not to cache in the test, set src dynamically img.src = 'https://www.gravatar.com/avatar/71094909be9f40bd576b1974a74966aa?s=48&d=identicon&r=PG&f=1'; console.log('height before', img.naturalHeight); // 0 await waitForImage(img); console.log('height after', img.naturalHeight); // 48 })();
<img src=""/>
function waitForImage(imgElem) { return new Promise((res, rej) => { if (imgElem.complete) { return res(); } imgElem.onload = () => res(); imgElem.onerror = () => rej(imgElem); }); } // test (async () => { const img = document.querySelector('#rightone'); // to not to cache in the test, set src dynamically img.src = 'https://www.gravatar.com/avatar/71094909be9f40bd576b1974a74966aa?s=48&d=identicon&r=PG&f=1'; console.log('height before', img.naturalHeight); // 0 await waitForImage(img); // success console.log('height after', img.naturalHeight); // 48 try { const failImg = document.querySelector('#wrongone'); failImg.src = 'https://wrongimage'; await waitForImage(failImg); // rejects after some time } catch(e) { console.log('failed to load image', e) } })();
<img id="rightone" src=""> <img id="wrongone" src="">
我的頁面上加載了緩慢的 CAPTCHA (1st_image) 圖像,我想僅在加載 CAPTCHA 圖像 (1st_image) 后顯示另一個圖像 (2nd_image)。 所以我不得不等待 CAPTCHA (1st_image) 圖像首先加載。
這是一個非常有效的解決方案,可以先等待圖像加載,然后再加載另一個圖像(不要忘記在他們等待其他圖像加載時顯示“請稍候!”圖像):
<script>
function checkImageLoad() {
if (document.getElementById("1st_image").complete == true) {
console.log("1st_image Loaded!");
}
document.getElementById("2nd_image").src = "http://example.org/2nd_image.png";
}
</script>
<body onload="checkImageLoad();">
<img id="1st_image" src="http://example.org/1st_image.png">
<img id="2nd_image" src="http://example.org/loading_please_wait.gif">
要么網速慢要么快,瀏覽器會等待整個頁面加載完所有圖片(即使它們是外部鏈接的)然后執行函數,所以只有在第一張圖片加載后才會顯示第二張圖片美好的。
高級說明:您可以在圖片的“src”中使用網頁網址,先加載網頁,然后再顯示圖片。 目的是從外部網頁加載 cookie,這可能會影響顯示的第二張圖像(如 CAPTCHA) 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.