通过 Javascript/jQuery 接收的字节数和图像的总字节数

发布于 2024-10-12 00:47:25 字数 2234 浏览 1 评论 0原文

我正在开发一个由 Javascript/jQuery 驱动的图像预加载器,但遇到了一些障碍。虽然目前它提供了基于 loaded_images/total_images 的进度,但考虑到一个页面可能有一千个 1kB 图像和一个 1MB 图像,这并不是很准确。

我正在寻找一种将文件大小合并到进度计算中的方法。现在,我研究了一些(跨浏览器兼容)捕获给定图像的文件大小的技巧,似乎对 Content-Length 的 Ajax 请求是最可靠的(就准确性而言)像这样:

var imageSizeTotal = 0;
var ajaxReqest = $.ajax({
    type: 'HEAD',
    url: 'path/to/image',
    success: function(message){
        imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
    }
});

现在,我发现这个方法非常有用,因为我可以在发生必要的请求时提供正在初始化状态消息。然而我现在的问题有两个:

  1. 是否有任何方法可以捕获给定图像对象加载的字节,也许使用 setInterval() 定期检查?否则,我又回到了大文件上挂着进度指示器的问题。
  2. 如何强制脚本的实际进度计算器等部分等待必要的 Ajax 请求完成(显示初始化或其他),以便它可以继续加载?

另外,这是我当前使用的脚本,它再次根据图像数量计算进度,无论文件大小或收到的字节数如何。

var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;

$('#preloaderCurtain')
    .bind('preloaderStart', function(){
        $(this)
            .show();
        $('*')
            .filter(function(e){
                if($(this).css('background-image') != 'none'){
                    preloaderTotal++;
                    return true;
                }
            })
            .each(function(index){
                preloaderCurrent = new Image();
                preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
                preloaderCurrent.onload = function(e){
                    preloaderLoaded++;
                    if(preloaderLoaded == preloaderTotal - 1){
                        $('#preloaderCurtain')
                            .trigger('preloaderComplete')
                    }
                    $('#preloaderCurtain')
                        .trigger('preloaderProgress')
                };
            });
    })
    .bind('preloaderComplete', function(){
        $(this)
            .fadeOut(500)
        startAnimation();
    })
    .bind('preloaderProgress', function(e){
        $('#preloaderProgress')
            .css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
            .text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
    })
    .trigger('preloaderStart');

希望一旦我解决了它的错误,我就能把它变成一个插件。

I'm working on a Javascript/jQuery powered image preloader, and have hit a bit of a snag. While as of currently it provides the progress based on loaded_images / total_images, this is not very accurate given a page could have a thousand 1kB images, and a single 1MB image.

I'm looking for a way to incorporate filesize into the progress calculations. Now, I've looked into some (cross browser compatible) tricks at capturing the filesize of a given image, and it seems that Ajax requests for Content-Length were the most reliable (in terms of accuracy) like so:

var imageSizeTotal = 0;
var ajaxReqest = $.ajax({
    type: 'HEAD',
    url: 'path/to/image',
    success: function(message){
        imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
    }
});

Now, I find this method to be quite useful, as I can provide a status message of Initializing while the necessary requests are taking place. However my issue now is two-fold:

  1. Is there any way possible to capture the bytes loaded of a given image object, perhaps using setInterval() to periodically check? Otherwise, I'm sort of back at the issue of the progress indicator hanging on large files.
  2. How can I force the actual progress calculator, etc., portion of the script to wait until the necessary Ajax requests are completed (displaying Initializing or whatever), so it can go ahead with the loading?

Also, here's the script I currently use, which again, calculates progress based on the number of images, regardless of filesize or bytes received.

var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;

$('#preloaderCurtain')
    .bind('preloaderStart', function(){
        $(this)
            .show();
        $('*')
            .filter(function(e){
                if($(this).css('background-image') != 'none'){
                    preloaderTotal++;
                    return true;
                }
            })
            .each(function(index){
                preloaderCurrent = new Image();
                preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
                preloaderCurrent.onload = function(e){
                    preloaderLoaded++;
                    if(preloaderLoaded == preloaderTotal - 1){
                        $('#preloaderCurtain')
                            .trigger('preloaderComplete')
                    }
                    $('#preloaderCurtain')
                        .trigger('preloaderProgress')
                };
            });
    })
    .bind('preloaderComplete', function(){
        $(this)
            .fadeOut(500)
        startAnimation();
    })
    .bind('preloaderProgress', function(e){
        $('#preloaderProgress')
            .css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
            .text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
    })
    .trigger('preloaderStart');

Hopefully I'll be able to turn this into a plugin, once I work the bugs out of it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷离° 2024-10-19 00:47:25

看起来这里提出并回答了类似的问题:

XmlHttpRequest.responseText while在 Chrome 中加载(readyState==3)

和此处:

Comet Jetty/Tomcat,Firefox 和 Chrome 存在一些浏览器问题

基本上 - .responseText.length 适用于 Firefox 和 iPhone,.responseBody.length 适用于 IE,WebSockets 适用于 Chrome。

第二个线程建议 bayeux/dojo 为您将所有这些封装到更高级别的 API 中,这样您就不必自己编写。

It looks like a similar question was asked and answered here:

XmlHttpRequest.responseText while loading (readyState==3) in Chrome

and here:

Comet Jetty/Tomcat, having some browser issues with Firefox and Chrome

Basically - .responseText.length for Firefox and iPhone, .responseBody.length for IE, WebSockets for Chrome.

The second thread suggests bayeux/dojo encapsulate all this for you into a higher-level API so you don't have to write it yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文