Câu hỏi Cách chính thức để yêu cầu jQuery chờ tất cả các hình ảnh tải trước khi thực hiện điều gì đó


Trong jQuery khi bạn làm điều này:

$(function() {
   alert("DOM is loaded, but images not necessarily all loaded");
});

Nó đợi DOM tải và thực thi mã của bạn. Nếu tất cả các hình ảnh không được tải thì nó vẫn thực thi mã. Điều này rõ ràng là những gì chúng tôi muốn nếu chúng tôi đang khởi tạo bất kỳ công cụ DOM nào như hiển thị hoặc ẩn các phần tử hoặc đính kèm các sự kiện.

Hãy nói rằng mặc dù tôi muốn một số hình ảnh động và tôi không muốn nó chạy cho đến khi tất cả các hình ảnh được tải. Có một cách chính thức trong jQuery để làm điều này?

Cách tốt nhất tôi có là sử dụng <body onload="finished()">, nhưng tôi không thực sự muốn làm điều đó trừ khi tôi phải làm vậy.

Lưu ý: Có một lỗi trong jQuery 1.3.1 trong Internet Explorer thực sự chờ tất cả hình ảnh tải trước khi thực thi mã bên trong $function() { }. Vì vậy, nếu bạn đang sử dụng nền tảng đó, bạn sẽ nhận được hành vi mà tôi đang tìm kiếm thay vì hành vi chính xác được mô tả ở trên.


601
2018-02-13 06:56


gốc


không $("img").load() công việc? - think123
Tôi nghĩ rằng nó có thể đáng nói đến nếu bạn thiết lập các thuộc tính kích thước, bạn ca an toàn thực hiện một số mã trong chức năng sẵn sàng dựa vào các kích thước đó. Với php bạn có thể lấy chúng với php.net/manual/en/function.getimagesize.php khi tải lên để lưu trữ chúng trong db hoặc trước khi xuất ra trình duyệt. - Alqin
nếu bạn muốn một cái gì đó làm một công việc đáng kinh ngạc, thì hãy xem thư viện javascript được tải lên cực kỳ tốt và phổ biến được đề cập trong câu trả lời dưới đây stackoverflow.com/a/26458347/759452 - Adrien Be
"Ở đây tôi đã tìm thấy bất cứ điều gì ngoại trừ một cách chính thức." - Léon Pelletier


Các câu trả lời:


Với jQuery, bạn sử dụng $(document).ready() để thực hiện điều gì đó khi DOM được tải và $(window).on("load", handler) để thực hiện một cái gì đó khi tất cả những thứ khác được tải là tốt, chẳng hạn như hình ảnh.

Có thể thấy sự khác biệt trong tệp HTML hoàn chỉnh sau, miễn là bạn có jollyroger Các tệp JPEG (hoặc các tệp phù hợp khác):

<html>
    <head>
        <script src="jquery-1.7.1.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                alert ("done");
            });
        </script>
    </head><body>
        Hello
        <img src="jollyroger00.jpg">
        <img src="jollyroger01.jpg">
        // : 100 copies of this
        <img src="jollyroger99.jpg">
    </body>
</html>

Với điều đó, hộp cảnh báo xuất hiện trước khi hình ảnh được tải, bởi vì DOM đã sẵn sàng tại thời điểm đó. Nếu bạn thay đổi:

$(document).ready(function() {

vào:

$(window).on("load", function() {

thì hộp cảnh báo sẽ không xuất hiện cho đến sau các hình ảnh được tải.

Do đó, để chờ cho đến khi toàn bộ trang đã sẵn sàng, bạn có thể sử dụng một cái gì đó như:

$(window).on("load", function() {
    // weave your magic here.
});

982
2018-02-13 07:03



trán đập 1 hoàn toàn quên điều đó. $ (cửa sổ) .load () sẽ không kích hoạt cho đến khi hình ảnh được thực hiện. - Paolo Bergantino
Tôi đã làm như vậy. Thậm chí, đọc qua một câu trả lời không biết đó là tôi và vẫn không hiểu nó. - Rimian
Chỉ cần một lưu ý - điều này dường như không hoạt động trong Chromium (và tôi đoán Chrome). Sự kiện $ (window) .ready dường như kích hoạt giống như $ (document) .ready - trước khi hình ảnh được hoàn thành. - Nathan Crause
nhưng đó là $ (cửa sổ) .load (function ()) - TJ-
@KyorCode Bạn có chắc chắn nó không chỉ vì những hình ảnh trong IE được lưu trữ? Nếu điều đó xảy ra, chúng sẽ không kích hoạt sự kiện "tải". bài viết này giúp giải quyết vấn đề này. - Jamie Barker


Tôi đã viết một plugin có thể kích hoạt các cuộc gọi lại khi các hình ảnh được tải trong các phần tử hoặc kích hoạt một lần cho mỗi lần tải hình ảnh.

Nó tương tự như $(window).load(function() { .. }), ngoại trừ nó cho phép bạn xác định bất kỳ bộ chọn nào để kiểm tra. Nếu bạn chỉ muốn biết khi nào tất cả hình ảnh trong #content (ví dụ) đã tải, đây là plugin cho bạn.

Nó cũng hỗ trợ tải hình ảnh được tham chiếu trong CSS, chẳng hạn như background-image, list-style-image, v.v.

waitForImages jQuery plugin

Sử dụng ví dụ

$('selector').waitForImages(function() {
    alert('All images are loaded.');
});

Ví dụ về jsFiddle.

Có thêm tài liệu trên trang GitHub.


151
2018-03-02 05:45



Cảm ơn bạn!! $ .load () đã không làm việc cho tôi, nhưng điều này thực hiện thủ thuật một cách hoàn hảo. - Fraxtil
Tôi sử dụng phiên bản Chrome 22.0.1229.94 và plugin này, và tôi đã cố gắng đọc các offset từ các hình ảnh được tải trong waitFormImages: ('img selector').each(function(index) { var offset = $(this).offset(); ...}); Tuy nhiên, offset.top vẫn bằng 0. Tại sao? - basZero
@ basZero Khó nói mà không cần thêm ngữ cảnh. Vui lòng nêu vấn đề về Vấn đề trang. - alex
@Batist Xong: D - alex
Về cơ bản nó tương tự như imagesLoaded nhưng nó cũng hoạt động với srcsets. Chính xác những gì tôi đang tìm kiếm! Plugin tuyệt vời! - Fabian Schöner


$(window).load() sẽ chỉ hoạt động lần đầu tiên trang được tải. Nếu bạn đang làm công cụ năng động (ví dụ: bấm vào nút, chờ đợi cho một số hình ảnh mới để tải), điều này sẽ không hoạt động. Để đạt được điều đó, bạn có thể sử dụng plugin của tôi:

Bản giới thiệu

Tải về

/**
 *  Plugin which is applied on a list of img objects and calls
 *  the specified callback function, only when all of them are loaded (or errored).
 *  @author:  H. Yankov (hristo.yankov at gmail dot com)
 *  @version: 1.0.0 (Feb/22/2010)
 *  http://yankov.us
 */

(function($) {
$.fn.batchImageLoad = function(options) {
    var images = $(this);
    var originalTotalImagesCount = images.size();
    var totalImagesCount = originalTotalImagesCount;
    var elementsLoaded = 0;

    // Init
    $.fn.batchImageLoad.defaults = {
        loadingCompleteCallback: null, 
        imageLoadedCallback: null
    }
    var opts = $.extend({}, $.fn.batchImageLoad.defaults, options);

    // Start
    images.each(function() {
        // The image has already been loaded (cached)
        if ($(this)[0].complete) {
            totalImagesCount--;
            if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
        // The image is loading, so attach the listener
        } else {
            $(this).load(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // An image has been loaded
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
            $(this).error(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // The image has errored
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
        }
    });

    // There are no unloaded images
    if (totalImagesCount <= 0)
        if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
};
})(jQuery);

48
2017-07-26 20:18



không có tùy chọn để tải xuống này .. - Amyth
chỉ trong trường hợp ai đó cần một ví dụ sử dụng cho plugin BatchImagesLoad: yankov.us/batchImageLoad - Jonathan Marzullo
Tôi có nghĩa là không thiếu tôn trọng nhưng người ta không thể dựa vào "chỉ" trên từ của bạn liên quan đến độ tin cậy của plugin của bạn. Như đã đề cập trong Yevgeniy Afanasyevcâu trả lời của, imagesLoaded thực hiện công việc tốt hơn nhiều ở đây và bao gồm trường hợp sử dụng mà bạn đã đề cập cùng với nhiều trường hợp góc khác (xem các vấn đề github đã được giải quyết). - Adrien Be


Đối với những người muốn được thông báo về việc hoàn thành tải xuống một hình ảnh duy nhất được yêu cầu sau $(window).load cháy, bạn có thể sử dụng phần tử hình ảnh load biến cố.

ví dụ.:

// create a dialog box with an embedded image
var $dialog = $("<div><img src='" + img_url + "' /></div>");

// get the image element (as a jQuery object)
var $imgElement = $dialog.find("img");

// wait for the image to load 
$imgElement.load(function() {
    alert("The image has loaded; width: " + $imgElement.width() + "px");
});

19
2017-10-23 21:17





Không ai trong số các câu trả lời cho đến nay đã đưa ra những gì có vẻ là giải pháp đơn giản nhất.

$('#image_id').load(
  function () {
    //code here
});

8
2017-11-14 13:15



Điều tốt đẹp về điều này là bạn có thể làm cho nó kích hoạt cho từng hình ảnh ngay sau khi tải. - Top Cat


Tôi khuyên bạn nên sử dụng imagesLoaded.js thư viện javascript.

Tại sao không sử dụng jQuery $(window).load()?

Được ansered trên https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951

Đó là vấn đề về phạm vi. imagesLoaded cho phép bạn nhắm mục tiêu một tập hợp các hình ảnh, trong khi $(window).load() nhắm mục tiêu tất cả tài sản - bao gồm tất cả hình ảnh, đối tượng, tệp .js và .css và thậm chí cả iframe. Nhiều khả năng, imagesLoaded sẽ kích hoạt sớm hơn $(window).load() vì nó đang nhắm mục tiêu một tập hợp tài sản nhỏ hơn.

Các lý do tốt khác để sử dụng hình ảnh được tải

  • chính thức được hỗ trợ bởi IE8 +
  • giấy phép: MIT License
  • phụ thuộc: không
  • trọng lượng (minified & gzipped): 7kb minified (light!)
  • download builder (giúp giảm cân): không cần, đã nhỏ
  • trên Github: YES
  • cộng đồng và cộng tác viên: khá lớn, hơn 4000 thành viên, mặc dù chỉ có 13 cộng tác viên
  • lịch sử và đóng góp: ổn định tương đối cũ (từ năm 2010) nhưng vẫn còn hoạt động

Tài nguyên


5
2018-06-02 19:36





Với jQuery tôi đi kèm với điều này ...

$(function() {
    var $img = $('img'),
        totalImg = $img.length;

    var waitImgDone = function() {
        totalImg--;
        if (!totalImg) alert("Images loaded!");
    };

    $('img').each(function() {
        $(this)
            .load(waitImgDone)
            .error(waitImgDone);
    });
});

Bản giới thiệu : http://jsfiddle.net/molokoloco/NWjDb/


4
2017-10-20 03:52



Tôi phát hiện ra rằng điều này sẽ không hoạt động đúng nếu trình duyệt trả về phản hồi 304 Not Mofified cho hình ảnh có nghĩa là hình ảnh được lưu trong bộ nhớ cache. - JohnyFree


Sử dụng imageLoaded PACKAGED v3.1.8 (6.8 Kb khi thu nhỏ). Nó là tương đối cũ (kể từ năm 2010) nhưng vẫn còn hoạt động dự án.

Bạn có thể tìm thấy nó trên github: https://github.com/desandro/imagesloaded

Trang web chính thức của họ: http://imagesloaded.desandro.com/

Tại sao nó tốt hơn sử dụng:

$(window).load() 

Vì bạn có thể muốn tải hình ảnh động như sau: jsfiddle

$('#button').click(function(){
    $('#image').attr('src', '...');
});

1
2018-04-01 19:25



Trên thực tế, tải hình ảnh không hỗ trợ thay đổi trình duyệt chéo giá trị thuộc tính src. Bạn phải tạo phần tử hình ảnh mới mỗi lần. Hãy thử nó trên Firefox và bạn sẽ thấy vấn đề xuất hiện. - Adrien Be
Điểm tốt, tôi đã chỉ được thử nghiệm trên Google chrome và IE-11 được nêu ra. Nó đang hoạt động. Cảm ơn. - Yevgeniy Afanasyev
Tôi đã thêm vấn đề qua trình duyệt này trong câu hỏi của mình stackoverflow.com/q/26927575 vào điểm "Bạn không thể làm gì với hình ảnh được tải lên", hãy xem vấn đề liên quan đến hình ảnh được tải xuống trên Github github.com/desandro/imagesloaded/issues/121 - Adrien Be