2017-10-18 64 views
3

我的目標是在html中使用style['background-image']加載一些圖像,但是當我將代碼放到Ajax中時,出現了一些問題。
如果我使用異步AJAX,圖像負載次序是反向;而我使用同步ajax,圖像加載命令是正常的。
尤其是,它發生在鉻。在Firefox中是正常的。它是一個關於圖像加載的鉻的錯誤?

HTML結構是這樣的

<div class="container"> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
    <div class="test"></div> 
</div> 

很簡單,當我使用同步AJAX,這樣

function Ajax(url) { 
     let xhr = new XMLHttpRequest() 
     xhr.onreadystatechange =() => { 
      if (xhr.readyState === 4 && xhr.status === 200) { 
       let slides = Array.from(document.querySelectorAll('.test')) 
       for (let i = 1; i < 20; i++) { 
        slides[i].style['background-image'] = `url(/data/gallery/1125425/content/${i})` 
       } 
      } 
     } 
     xhr.open('get', url, false) 
     xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded') 
     xhr.send() 
    } 
    Ajax('https://api.github.com') 

而結果的JS代碼是這樣enter image description here

我們可以找到它的正常,就像我們認爲它應該是

Hower ver,當將異步從false更改爲true時,結果是這樣的。

爲了顯示url並不重要,我使用github的公共API。 而現在我們看到的結果是在網絡面板 enter image description here

我們可以看到最後的影像第一次加載,只是一個相反的順序與我們的第一次嘗試比較。

事實上,這種現象不會在Firefox發生,所以我想它是在瀏覽器的錯誤?

我已經把我的代碼爲Codepen
UPDATE:我認爲造成無極LT年代,經過後來我發現事實並非如此。所以我改變標題

+0

哇,這真的很奇怪,但是這看起來像是一個需要調試的問題,你能夠添加Codepen或類似的東西,以便調試嗎? –

+0

我知道這只是一個例子,但你應該從i = 0開始計算,所以你不會錯過第一個元素。 – GrafWampula

+0

@GhassenLouhaichi我已經更新並將代碼放入Codepen,如果您要調試此代碼,您可以更改圖片網址 – Messiah

回答

2

調試你的codepen,我發現,任何一種範圍包裝的顛倒順序。這一個:

let slides = Array.from(document.querySelectorAll('.test')) 
    for (let i = 0; i < slides.length; i++) { 
    (() => slides[i].style['background-image'] = `url(/data/gallery/1125425/content/${i})`)(); 
    } 

這:

(() => { 
    let slides = Array.from(document.querySelectorAll('.test')) 
    for (let i = 0; i < slides.length; i++) { 
    slides[i].style['background-image'] = `url(/data/gallery/1125425/content/${i})` 
    } 
})(); 

所以無極無關與,我猜。

但是我也會說,轉發順序(在我的情況下)不是嚴格的轉發順序,它是越野車:0, 1, 2, 3, 4, 5, 10, 8, 7, 19, etc並且這個順序在會話期間不會改變。

+0

感謝您的回答,但我發現您的代碼不會顛倒訂單。而Promise與你所說的無關,我認爲它是由ajax'async'造成的。你可以在問題描述中看到我的更新 – Messiah

0

不,它本身並不是一個bug,即使它仍然很奇怪。

發生這種情況的原因是瀏覽器在此for循環期間不會重新計算元素的樣式,但僅在js執行結束並且所有DOM更改完成後纔會重新計算元素的樣式。

在接下來的步驟中會發生什麼(風格重新計算 - >新資源加載)是由實現。

如果你想有一個固定的順序(即使我不明白你爲什麼會),你可以在每次循環強制迴流:

(() => { 
 
    let slides = Array.from(document.querySelectorAll('.test')) 
 
    for (let i = 0; i < slides.length; i++) { 
 
    slides[i].style['background-image'] = `url(/${i})` 
 
    document.body.offsetWidth; // force reflow 
 
    } 
 
})(); 
 
console.log("check the 'Network Panel' of your dev-tools");
<div class="container"> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
    <div class="test"></div> 
 
</div>