ajax - 在写入页面之前检查图像是否已加载

时间:2010-08-06 11:08:08

标签: jquery ajax image

在我认为这个项目结束后,我遇到了一个问题。它在我的本地服务器上工作得很好但是当我实时推送代码时,图像可能需要半秒才能正确加载,导致在加载图像上弹出一个小页面缩略图。哎呀

alt text http://img815.imageshack.us/img815/985/loading.jpg

发生什么事了?首先,一个函数在window.load上运行,它创建了大量列表项,加载gif作为bg图像。

然后此函数将<img>标记弹出到第一个列表项中,onload调用第二个函数

第二个函数循环遍历XML文件,并将xml中的URL包装在<img>标记中,并将其放在下一个空LI中。这就是问题所在。目前,它在<img src=$variable onload=loadnextimage() />实际加载之前将其放入List项目。

我的代码:

$(window).load(function() {
            txt="";
            for(d=0;d<100;d++)
            {
                txt=txt + "<li class='gif' id='loading"+d+"'></li>"; 

            }
            document.getElementById('page-wrap').innerHTML=txt;
            document.getElementById('loading0').innerHTML="<img src='images/0.jpg' onLoad='loadImages(0)' />";
        });
        function loadImages(i){ 
            i++
            $.ajax
            ({
                type: "GET",
                url: "sites.xml",
                dataType: "xml",
                async: "true",
                success: function(xml) 
                {
                    var img = $(xml).find('image[id=' + i + ']'),
                    id = img.attr('id'),
                    url = img.find('url').text();
                    $('#loading'+i).html('<img src="'+url+'" onLoad="loadImages('+i+')" />').hide();
                    $('#loading'+i).fadeIn();
                }
            });
        }

我有一种感觉,实现这个我如何设置它可能相当棘手,我有一种感觉我可能需要创建一个img对象并等待加载???

一旦页面被缓存,加载显然工作正常,但是在他第一次加载时有点痛苦,所以我需要解决这个问题。 任何建议欢迎:)谢谢

7 个答案:

答案 0 :(得分:2)

success: function(xml) {
    var img = $(xml).find('image[id=' + i + ']'),
        id = img.attr('id'),
        url = img.find('url').text();
    // hide loading
    $('#loading'+i).hide();
    $('<img src="'+url+'" onLoad="loadImages('+i+')" />').load(function() {
       // after image load
       $('#loading' + i).html(this); // append to loading
       $('#loading'+i).fadeIn(); // fadeIn loding
    });
}

答案 1 :(得分:2)

在我看来,你正在苦苦思索。有时解决方案是改变思维方式。这完全取决于你。 One of my favorite related books.

我的建议有类似下面的代码。它并不完全是你需要的......但

Demo on Fiddle

<强> HTML:

<div class="frame" title="Tochal Hotel">
    <div class="loadingVitrin">
        <img src="http://photoblog.toorajam.com/photos/4cf85d53afc37de7e0cc9fa207c7b977.jpg" onload="$(this).fadeTo(500, 1);">
    </div>
</div>​

<强> CSS:

html, body {
    padding: 10px;
}

.frame {
    z-index: 15;
    box-shadow: 0 0 10px gray;
    width: 350px;
    height: 350px;
    border: gray solid 1px;
    padding: 5px;
    background: #F0F9FF;
}

.loadingVitrin {
    z-index: 15;
    width: 350px;
    height: 350px;
    overflow: hidden;
    background: url("http://photoblog.toorajam.com/images/main/ajax-loader.gif") no-repeat center;
}

.loadingVitrin img {
    display: none;
    height: 350px;
}
​

答案 2 :(得分:0)

我遇到了同样的问题。试图得到答案我达成了你的问题。无论如何,我设法解决它的方式是放置:

<div style="visibility:hidden; position:absolute; margin-left:-10000px;">
   <img src="foo.png" /> 
    // place all the images in here that you eventually will need
</div>

图像将以异步方式下载。如果您已有图像,则不会再次下载它将存储在浏览器的缓存中。因此,如果用户在第一页中花费30秒,那么整个网站将会更快。这取决于您网站的大小。但这解决了使用小型网站时的问题。

我知道这不是一个真正的解决方案我会在你的问题上开始赏金。

答案 3 :(得分:0)

感谢@thecodeparadox我最终得到了:

$.get("SomePage.aspx", "", function (r) {

    // r = response from server

    // place response in a wrapper
    var wrapper = $('<div id="wrapper" style=""></div>').html(r);

    // need to write the images somewhere in the document for the event onload to fire
    // loading content is a hidden div in my document.
    $(document).append(wrapper);
    //$("#LoadingContent").html("").append(wrapper);

    var counter = 0;

    var images = $(wrapper).find("img"); // get all the images from the response

    // attach the onload event to all images
    images.bind("load", function () {

        counter++;

        if (counter == images.size()) { // when all images are done loading
            // we are now save to place content
            // place custom code in here
            // executeSomeFuction();
            $("#AjaxContent").html(r); 
            $(document).remove(wrapper);
        }
    });

}, "text");

答案 4 :(得分:0)

您只需使用Image()对象预加载每个图像。 下面给出的脚本非常容易使用。只需在“callbackFN()”中写入你想做的任何代码然后你就“preload_images(array_img)”。更准确地说:

   var array_images = [];
   $.ajax
            ({
                type: "GET",
                url: "sites.xml",
                dataType: "xml",
                async: "true",
                success: function(xml) 
                {
                    var img = $(xml).find('image[id=' + i + ']'),
                    id = img.attr('id'),
                    url = img.find('url').text();
                    array_images.push(url);
                }
            });




// Your callback function after loading:
function callbackFN() {
   // Do whatever you want HERE
   // Pretty much this:
   for (var i = 1; i<=array_images.length; i++) {
      $('#loading'+i).html('<img src="'+url+'" />').hide();
      $('#loading'+i).fadeIn();
   }
}


var array_obj = Array();
var iKnowItsDone = false;
// Timer (IE BULLET PROOF)
var ieCheckImgTimer;
        // Check if images are loaded
    function images_complete(obj) {
        var max = obj.length;
        var canGo = true;
        for (var i = 0; i<max; i++){
            if (!obj[i].complete) {
                canGo = false;
            }
        }
        return canGo;
    }
    // Loop to check the images
    function preload_images(obj) {
        var max = obj.length;
        for (var i = 0; i<max; i++){
            var img = new Image();
            img.src = obj[i];
            array_obj.push(img);

            img.onload = function() {
                check_img();
            }
        }
        ieCheckImgTimer = setTimeout('check_img()',250);
    }

        // Timer to see if all the images are loaded yet. Waits till every img are loaded
    function check_img() {
        if (ieCheckImgTimer) {
            clearTimeout(ieCheckImgTimer);
        }
        if (images_complete(array_obj) && !iKnowItsDone) {
            iKnowItsDone = true;
            callbackFN();
        }
        else {
            ieCheckImgTimer = setTimeout('check_img()',250);
        }
    }

答案 5 :(得分:0)

试试这个:

ThumbImage = document.createElement("img");
ThumbImage.src = URL;

ThumbImage.onload = function(){
    //function After Finished Load                      
}

答案 6 :(得分:0)

您希望确保图像由浏览器加载,即在浏览器的缓存中加载,然后再将其添加到文档中:

// create an image element
$('<img />')
    // add a load event handler first
    .load(function() {
        // append the image to the document after it is loaded
        $('#loading').append(this);
    })
    // then assign the image src
    .attr('src', url);

因此,对于您的代码,我会这样做:

$(window).load(function() {
    var txt="";
    for(var d=0;d<100;d++)
    {
        txt=txt + "<li class='gif' id='loading"+d+"'></li>"; 

    }
    document.getElementById('page-wrap').innerHTML=txt;

    $('<img />')
        .load(function() {
            $('#loading0').append(this);
            loadImages(0);
        })
        .attr('src', 'images/0.jpg');
});
function loadImages(i){ 
    i++
    $.ajax
    ({
        type: "GET",
        url: "sites.xml",
        dataType: "xml",
        async: "true",
        success: function(xml) 
        {
            var img = $(xml).find('image[id=' + i + ']'),
            id = img.attr('id'),
            url = img.find('url').text();

            $('<img />')
                .load(function() {
                    $('#loading' + i)
                        .append(this)
                        .hide()
                        .fadeIn();
                    loadImages(i);
                })
                .attr('src', url);
        }
    });
}

也许这只是你的示例代码,但我不明白为什么不能同时加载0.jpg和sites.xml或其他图像:

$(window).load(function() {
    var buf = [], d;
    for (d = 0; d < 100; d++) {
        buf.push('<li class="gif" id="loading' + d + '"></li>');
    }
    $('#page-wrap').html(buf.join(''));

    $('<img />')
        .load(function() {
            $('#loading0').append(this);
        })
        .attr('src', 'images/0.jpg');

    $.ajax({
        type: 'GET',
        url: 'sites.xml',
        dataType: 'xml',
        async: true,
        success: function(xml) {
            var img, id, url, i;

            xml = $(xml);

            for (i = 1; i < 100; i++) {
                img = xml.find('image[id=' + i + ']');
                id = img.attr('id');
                url = img.find('url').text();

                $('<img />')
                    .load(function() {
                        $('#loading' + i)
                            .append(this)
                            .hide()
                            .fadeIn();
                    })
                    .attr('src', url);
            }
        }
    });
});