JS动态加载响应式图像并找出它们何时被加载

时间:2017-01-23 10:27:24

标签: javascript image media-queries responsive preload

背景:

有一个网站有很多很多图片。 但是,用户只需要立即接收前15张图像。



document.addEventListener("DOMContentLoaded", function()
{
	function loaded_3()
	{
	document.getElementById("left").innerHTML += "<br><br><strong>ALL DONE :)</strong><br><br>";
	}

	function loaded_2()
	{
	document.getElementById("left").innerHTML += "<br><br><strong>OK - images 16-30 have also loaded successfully!</strong><br>NOW LOADING THE REMAINING 5 IMAGES!<br>";


	var last_divs = Array.prototype.slice.call(document.querySelectorAll('[data-last-id]'));

		last_divs.forEach(function(element)
		{
		element.setAttribute('id', element.getAttribute('data-last-id'));
		document.getElementById("left").innerHTML += 'id="' + element.getAttribute('data-last-id') + '" was set successfully!<br>';
		});

	window.removeEventListener("load", loaded_2);
	window.addEventListener("load", loaded_3);
	}

	function loaded_1()
	{
	document.getElementById("left").innerHTML += "<strong>OK - images 1-15 have loaded successfully!</strong><br><br>";

	var divs = Array.prototype.slice.call(document.querySelectorAll('[data-id]'));

		divs.forEach(function(element)
		{
		element.setAttribute('id', element.getAttribute('data-id'));
		document.getElementById("left").innerHTML += 'id="' + element.getAttribute('data-id') + '" was set successfully!<br>';
		});

	window.removeEventListener("load", loaded_1);
	window.addEventListener("load", loaded_2);
	}

	window.addEventListener("load", loaded_1);
});
&#13;
*
{
padding:0px;
margin:0px;
border-style:none;
box-sizing:border-box;
}

html, body
{
width:100%;
height:100%;
}

#left
{
position:absolute;
width:400px;

left:0px;
top:0px;
bottom:0px;
background-color:#ffcc00;
padding:20px;
}

#right
{
position:absolute;
left:400px;
top:0px;
right:0px;
bottom:0px;
background-color:#eeeeee;
padding:20px;
}


#one { background-image:url(https://placehold.it/999x999/ffcc00/cc33ff); }
#two { background-image:url(https://placehold.it/999x999/ff0000/000000); }
#three { background-image:url(https://placehold.it/999x999/00cc00/33cccc); }
#four { background-image:url(https://placehold.it/999x999/330033/ff33ff); }
#five { background-image:url(https://placehold.it/999x999/ffcccc/0033ff); }
#six { background-image:url(https://placehold.it/999x999/bbcc11/dddd00); }
#seven { background-image:url(https://placehold.it/999x999/0033bb/222bbb); }
#eight { background-image:url(https://placehold.it/999x999/2211bb/00bb11); }
#nine { background-image:url(https://placehold.it/999x999/ffcc00/22ccff); }
#ten { background-image:url(https://placehold.it/999x999/ffcc00/33ccff); }
#eleven { background-image:url(https://placehold.it/999x999/f0cc00/333333); }
#twelve { background-image:url(https://placehold.it/999x999/f1c20b/c13bf2); }
#thirteen { background-image:url(https://placehold.it/999x999/f0cd00/cf33f0); }
#fourteen { background-image:url(https://placehold.it/999x999/ff0b01/0001ff); }
#fifteen { background-image:url(https://placehold.it/999x999/ffbb00/dd31ff); }
#sixteen { background-image:url(https://placehold.it/999x999/ffd100/cc33ff); }
#seventeen { background-image:url(https://placehold.it/999x999/ffec10/000000); }
#eighteen { background-image:url(https://placehold.it/999x999/fbccfd/ff33ff); }
#nineteen { background-image:url(https://placehold.it/999x999/ccccff/cf33f0); }
#twenty { background-image:url(https://placehold.it/999x999/00ccee/cc33ff); }
#twentyone { background-image:url(https://placehold.it/999x999/ddccee/dddd00); }
#twentytwo { background-image:url(https://placehold.it/999x999/bbee00/cc33ff); }
#twentythree { background-image:url(https://placehold.it/999x999/11c000/c13bf2); }
#twentyfour { background-image:url(https://placehold.it/999x999/44c200/00bb11); }
#twentyfive { background-image:url(https://placehold.it/999x999/22ca00/33cccc); }
#twentysix { background-image:url(https://placehold.it/999x999/bbcf00/cc33ff); }
#twentyseven { background-image:url(https://placehold.it/999x999/ffbb00/00bb11); }
#twentyeight { background-image:url(https://placehold.it/999x999/eedd00/cc33ff); }
#twentynine { background-image:url(https://placehold.it/999x999/00ff00/33ccff); }
#thirty { background-image:url(https://placehold.it/999x999/220000/c13bf2); }

.testdiv
{
width:30px;
height:30px;
overflow:hidden;
margin:5px;

display:inline-block;
font-weight:bold;
font-size:30px;
color:#ffffff;
text-align:center;
line-height:30px;
}
&#13;
<div id="left"></div>

<div id="right">

<div class="testdiv" id="one">1</div>
<div class="testdiv" id="two">2</div>
<div class="testdiv" id="three">3</div>
<div class="testdiv" id="four">4</div>
<div class="testdiv" id="five">5</div>
<div class="testdiv" id="six">6</div>
<div class="testdiv" id="seven">7</div>
<div class="testdiv" id="eight">8</div>
<div class="testdiv" id="nine">9</div>
<div class="testdiv" id="ten">10</div>
<div class="testdiv" id="eleven">11</div>
<div class="testdiv" id="twelve">12</div>
<div class="testdiv" id="thirteen">13</div>
<div class="testdiv" id="fourteen">14</div>
<div class="testdiv" id="fifteen">15</div>

<div class="testdiv" data-id="sixteen">16</div>
<div class="testdiv" data-id="seventeen">17</div>
<div class="testdiv" data-id="eighteen">18</div>
<div class="testdiv" data-id="nineteen">19</div>
<div class="testdiv" data-id="twenty">20</div>
<div class="testdiv" data-id="twentyone">21</div>
<div class="testdiv" data-id="twentytwo">22</div>
<div class="testdiv" data-id="twentythree">23</div>
<div class="testdiv" data-id="twentyfour">24</div>
<div class="testdiv" data-id="twentyfive">25</div>

<div class="testdiv" data-last-id="twentysix">26</div>
<div class="testdiv" data-last-id="twentyseven">27</div>
<div class="testdiv" data-last-id="twentyeight">28</div>
<div class="testdiv" data-last-id="twentynine">29</div>
<div class="testdiv" data-last-id="thirty">30</div>

</div> <!-- right -->
&#13;
&#13;
&#13;

加载前15张图像后,应立即加载下10张图像。 并且最后5张图像应该在前15张后加载,接下来的10幅图像加载完毕。

这是我尝试过的: https://filebin.net/01s7w1grpybvkiis/fourth.html

我的方法是设置一个id =&#34;&#34;只有,让CSS做媒体查询。 当然我可以使用JS加载图像(然后我可以很容易地找出哪些已加载),但我需要同时处理两者,CSS-width 也像素比率!! < / p>

因此我无法在JS中加载特定图像,因为要加载的背景图像将是不同的,具体取决于CSS宽度和像素比率(在我的测试用例中未实现,但您需要获取此信息! )。

这就是为什么我一起尝试使用JS和CSS的原因(参见示例:https://filebin.net/01s7w1grpybvkiis/fourth.html

我找到了一个JS库(名为enquire.js),它说它可以在纯JS中进行媒体查询,但是它无法使用媒体查询来获得像素比,所以我再次尝试使用CSS媒体查询。

我如何为此编写纯JavaScript解决方案?我不想在这个阶段使用jQuery。

1 个答案:

答案 0 :(得分:0)

到目前为止,这就是我所做的:

console.clear();
        checkBackgroundLoad();
        var imgSrc = [];
        document.body.addEventListener('DOMSubtreeModified', function () {
            var imgs = document.getElementsByTagName("IMG");
            //console.log(imgs);
            for (var i = 0; i < imgs.length; i++) {
                var src = imgs[i].getAttribute('src');
                if (imgSrc.indexOf(src) > -1) return;
                imgSrc.push(src);
                if (imgs[i].complete) continue;
                imgs[i].onload = function () { console.log("Loaded Image"); }
                imgs[i].onerror = function () { console.log("Fail to Load Image"); }
            }

            checkBackgroundLoad();

        }, false);

        function checkBackgroundLoad() {
            var all = document.getElementsByTagName("*");
            for (var i = 0; i < all.length; i++) {
                var id = all[i].getAttribute("id");
                var style = all[i].currentStyle || window.getComputedStyle(all[i], false);
                //console.log(style);
                var bi = style.backgroundImage.slice(4, -1);
                LoadBackgroundImage(bi, id);
            }
        }

        var uniqueImg = [];
        var countLoad = 0;
        var completionCallback = undefined;

        function LoadBackgroundImage(bi, id) {
            if (bi.length < 1) return;
            if (countLoad < 1) return;
            bi = bi.replace(new RegExp('"', 'g'), '');
            //var imageName = bi.replace(/[^a-zA-Z0-9]/g, "");
            if (uniqueImg.indexOf(bi) != -1) {
                //countLoad--;
                return;
            }
            uniqueImg.push(bi);
            console.log(id);
            var img = new Image();
            img.onload = function () {
                console.log("Loaded Background Image");
                LogLoad(id);
                CompleteLoad();
            };
            img.onerror = function () {
                console.log("Fail to load Background Image");
                CompleteLoad();
            }
            img.src = bi;
        }

        function CompleteLoad() {
            countLoad--;
            //console.log(countLoad);
            if (countLoad > 0) return;
            if (countLoad == 0) {
                //uniqueImg = [];
                completionCallback();
                return;
            }
        }

        function LogLoad(id) {
            document.getElementById("left").innerHTML += 'id="' +
                id +
                '" Loaded <br>';
        }


        function firstBatch() {
            var divs = Array.prototype.slice.call(document.querySelectorAll('[first-id]'));
            countLoad = divs.length;
            completionCallback = secondBatch;
            divs.forEach(function (element) {
                element.setAttribute('id', element.getAttribute('first-id'));
                document.getElementById("left").innerHTML += 'id="' +
                    element.getAttribute('first-id') +
                    '" start loading!<br>';
            });
        }

        var secondBatch = function () {
            var divs = Array.prototype.slice.call(document.querySelectorAll('[data-id]'));
            countLoad = divs.length;
            completionCallback = thirdBatch;
            divs.forEach(function (element) {
                element.setAttribute('id', element.getAttribute('data-id'));
                document.getElementById("left").innerHTML += 'id="' +
                    element.getAttribute('data-id') +
                    '" start loading!<br>';
            });
        }

        var thirdBatch = function (callback) {
            var lastDivs = Array.prototype.slice.call(document.querySelectorAll('[data-last-id]'));
            countLoad = lastDivs.length;
            completionCallback = LastBatch;
            lastDivs.forEach(function (element) {
                element.setAttribute('id', element.getAttribute('data-last-id'));
                document.getElementById("left").innerHTML += 'id="' +
                    element.getAttribute('data-last-id') +
                    '" start loading!<br>';
            });
        }

        function LastBatch() {
            for (var i = 0; i < 10; i++) {
                document
                    .getElementById("right")
                    .innerHTML += '<img src="http://lorempixel.com/400/200/?' + i + '" style="width: 30px;height: 30px;" />';
            }
        }

        firstBatch();
{
padding:0px;
margin:0px;
border-style:none;
box-sizing:border-box;
}

html, body
{
width:100%;

}

#left
{
position:absolute;
width:400px;

left:0px;
top:0px;
bottom:0px;
background-color:#ffcc00;
padding:20px;
}

#right
{
position:absolute;
left:400px;
top:0px;
right:0px;
bottom:0px;
background-color:#eeeeee;
padding:20px;
}


#one { background-image:url(https://placehold.it/999x999/ffcc00/cc33ff); }
#two { background-image:url(https://placehold.it/999x999/ff0000/000000); }
#three { background-image:url(https://placehold.it/999x999/00cc00/33cccc); }
#four { background-image:url(https://placehold.it/999x999/330033/ff33ff); }
#five { background-image:url(https://placehold.it/999x999/ffcccc/0033ff); }
#six { background-image:url(https://placehold.it/999x999/bbcc11/dddd00); }
#seven { background-image:url(https://placehold.it/999x999/0033bb/222bbb); }
#eight { background-image:url(https://placehold.it/999x999/2211bb/00bb11); }
#nine { background-image:url(https://placehold.it/999x999/ffcc00/22ccff); }
#ten { background-image:url(https://placehold.it/999x999/ffcc00/33ccff); }
#eleven { background-image:url(https://placehold.it/999x999/f0cc00/333333); }
#twelve { background-image:url(https://placehold.it/999x999/f1c20b/c13bf2); }
#thirteen { background-image:url(https://placehold.it/999x999/f0cd00/cf33f0); }
#fourteen { background-image:url(https://placehold.it/999x999/ff0b01/0001ff); }
#fifteen { background-image:url(https://placehold.it/999x999/ffbb00/dd31ff); }
#sixteen { background-image:url(https://placehold.it/999x999/ffd100/cc33ff); }
#seventeen { background-image:url(https://placehold.it/999x999/ffec10/000000); }
#eighteen { background-image:url(https://placehold.it/999x999/fbccfd/ff33ff); }
#nineteen { background-image:url(https://placehold.it/999x999/ccccff/cf33f0); }
#twenty { background-image:url(https://placehold.it/999x999/00ccee/cc33ff); }
#twentyone { background-image:url(https://placehold.it/999x999/ddccee/dddd00); }
#twentytwo { background-image:url(https://placehold.it/999x999/bbee00/cc33ff); }
#twentythree { background-image:url(https://placehold.it/999x999/11c000/c13bf2); }
#twentyfour { background-image:url(https://placehold.it/999x999/44c200/00bb11); }
#twentyfive { background-image:url(https://placehold.it/999x999/22ca00/33cccc); }
#twentysix { background-image:url(https://placehold.it/999x999/bbcf00/cc33ff); }
#twentyseven { background-image:url(https://placehold.it/999x999/ffbb00/00bb11); }
#twentyeight { background-image:url(https://placehold.it/999x999/eedd00/cc33ff); }
#twentynine { background-image:url(https://placehold.it/999x999/00ff00/33ccff); }
#thirty { background-image:url(https://placehold.it/999x999/220000/c13bf2); }

.testdiv
{
width:30px;
height:30px;
overflow:hidden;
margin:5px;

display:inline-block;
font-weight:bold;
font-size:30px;
color:#ffffff;
text-align:center;
line-height:30px;
}
<div id="left"></div>

<div id="right">

    <div class="testdiv" first-id="one">1</div>
    <div class="testdiv" first-id="two">2</div>
    <div class="testdiv" first-id="three">3</div>
    <div class="testdiv" first-id="four">4</div>
    <div class="testdiv" first-id="five">5</div>
    <div class="testdiv" first-id="six">6</div>
    <div class="testdiv" first-id="seven">7</div>
    <div class="testdiv" first-id="eight">8</div>
    <div class="testdiv" first-id="nine">9</div>
    <div class="testdiv" first-id="ten">10</div>
    <div class="testdiv" first-id="eleven">11</div>
    <div class="testdiv" first-id="twelve">12</div>
    <div class="testdiv" first-id="thirteen">13</div>
    <div class="testdiv" first-id="fourteen">14</div>
    <div class="testdiv" first-id="fifteen">15</div>

    <div class="testdiv" data-id="sixteen">16</div>
    <div class="testdiv" data-id="seventeen">17</div>
    <div class="testdiv" data-id="eighteen">18</div>
    <div class="testdiv" data-id="nineteen">19</div>
    <div class="testdiv" data-id="twenty">20</div>
    <div class="testdiv" data-id="twentyone">21</div>
    <div class="testdiv" data-id="twentytwo">22</div>
    <div class="testdiv" data-id="twentythree">23</div>
    <div class="testdiv" data-id="twentyfour">24</div>
    <div class="testdiv" data-id="twentyfive">25</div>

    <div class="testdiv" data-last-id="twentysix">26</div>
    <div class="testdiv" data-last-id="twentyseven">27</div>
    <div class="testdiv" data-last-id="twentyeight">28</div>
    <div class="testdiv" data-last-id="twentynine">29</div>
    <div class="testdiv" data-last-id="thirty">30</div>

</div>