javascript - 使用 JavaScript 和 jQuery 预加载图像

标签 javascript jquery

我正在使用以下代码将一些 HTML 插入到一个 div 中,并预加载该 HTML 中可能包含的任何图像(html var 的数据实际上是从实际代码中的 AJAX 请求中获取的)。这是为了防止浏览器在显示 div 时加载获取的 HTML 图像(使用 slideDown 事件)——因为这会导致效果的流动性在加载图像中间过渡时被破坏。我想我可以使用隔行扫描的 JPEG,以便几乎立即知道图像的尺寸,但显然最好能找到一种更简洁的方法。 :P

var html = '<img src="images/test.jpg" alt="test" />';

$('div.content').hide().html(html);

$('div.content img').each(function(){

    var img = new Image();

    img.src = $(this).attr('src');

    $(this).attr('src', img.src);

});

$('div.content').slideDown('normal');

我正在使用 Image 对象并根据给定的建议对其进行后续分配 here , 但不幸的是,使用此方法的浏览器仍未缓存图像,因为 sildeDown() 效果仍会在图像加载时中断。

任何帮助或替代方法?非常感谢。

编辑 - 2009 年 9 月 21 日


进步了!结果是浏览器正在缓存图像,我只是没有给它时间这样做(它只需要一秒钟来加载 alert() 或 setInterval())。现在介绍可能是有史以来最困惑的代码 - 我正在使用无限循环来创建暂停。

新方法通过将一个函数(将每个图像的 src 添加到一个数组)绑定(bind)到该图像的成功加载事件来扩展上面的旧代码。然后它会陷入无限循环,因为它会等待所有图像都已加载并因此出现在数组中。这似乎是一种同步预加载图像的方法——但问题仍然存在; while() 循环出于某种原因会无限循环,即使所有图像都已加载,除非我添加一个 alert() 使其暂停片刻。

新代码:

var html = '<img src="images/test.jpg" alt="test" />';

$('div.content').hide().html(html);

// define usr variables object
$.usrvar = {};

// array of loaded images' urls
$.usrvar.images = [];

// boolean for whether this content has images (and if we should check they are all loaded later)
$.usrvar.hasimages = false;

// foreach of any images inside the content
$('div.content img').each(function(){

    // if we're here then this content has images..
    $.usrvar.hasimages = true;

    // set this image's src to a var
    var src = $(this).attr('src');

    // add this image to our images array once it has finished loading
    $(this).load(function(){

        $.usrvar.images.push(src);

    });

    // create a new image
    var img = new Image();

    // set our new image's src
    img.src = src;

});

// avoid this code if we don't have images in the content
if ($.usrvar.hasimages != false) {

    // no images are yet loaded
    $.usrvar.imagesloaded = false;

    // repeatedly cycle (while() loop) through all images in content (each() loop)
    while ($.usrvar.imagesloaded != true) {

        $('div.content img').each(function(){

            // get this loop's image src
            var src = $(this).attr('src');

            // if this src is in our images array, it must have finished loading
            if ($.usrvar.images.indexOf(src) != -1) {

                // set imagesloaded to trueai
                $.usrvar.imagesloaded = true;

            } else {

                // without the pause caused by this alert(), this loop becomes infinite?!
                alert('pause');

                // this image is not yet loaded, so set var to false to initiate another loop
                // (ignores whether imagesloaded has been set to true by another image, because ALL
                // need to be loaded
                $.usrvar.imagesloaded = false;

            }

        });

    }

}

$('div.content').slideDown('normal');

最佳答案

我提出了以下解决方案,但尚未经过测试,因此请注意 ;)

// HTML (any formatting possible)
// no src for the images: it is provided in alt which is of the form url::actualAlt
var html = "<p><img alt='images/test.jpg::test' /><br />Some Text<br /><img alt='images/test2.jpg::test2' /></p>";

$(document).ready(function() {

    // Reference to the content div (faster)
    var divContent = $("div.content");

    // Hide the div, put the HTML
    divContent.hide().html(html);

    // Webkit browsers sometimes do not parse immediately
    // The setTimeout(function,1) gives them time to do so
    setTimeout(function() {

        // Get the images
        var images = $("img",divContent);

        // Find the number of images for synchronization purpose
        var counter = images.length;

        // Synchronizer
        // will show the div when all images have been loaded
        function imageLoaded() {
            if (--counter<=0) $('div.content').slideDown('normal');
        }

        // Loading loop
        // For each image in divContent
        $.each(images,function() {
            // Get the url & alt info from the alt attribute
            var tmp = $(this).attr("alt").split("::");
            // Set the alt attribute to its actual value
            $(this).attr("alt",tmp[1]);
            // Wire the onload & onerror handlers
            this.onload = this.onerror = imageLoaded;
            // Set the image src
            this.src = tmp[0];
        });

    },1);

});

关于javascript - 使用 JavaScript 和 jQuery 预加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1451506/

相关文章:

javascript - www 和非 www 的 Nodejs session 问题

php - 如何判断 PHP 中哪个 Javascript 文件正在请求数据?

javascript - Ajax/Jquery 重定向调用不起作用

javascript - 使用支持 i.e 9 的 XMLHttpRequest 进行 AJAX 文件上传

javascript - jquery升级到1.6.1后附加函数执行

php - 在php行中插入多个值

javascript - 如何避免PHP中的警告框

javascript - 如何使用 JS/Jquery 将一个 div 覆盖在另外 2 个 div 上

jquery - 检索选中的复选框的值

javascript - 实际时间网页已与jquery一起使用