2017-10-18 69 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>