Hãy xem xét những điều sau đây (mong manh) mã JavaScript:Nên đặt hình ảnh src thành URL dữ liệu có sẵn ngay lập tức không?
var img = new Image;
img.src = "data:image/png;base64,..."; // Assume valid data
// Danger(?) Attempting to use image immediately after setting src
console.log(img.width, img.height);
someCanvasContext.drawImage(img, 0, 0);
// Danger(?) Setting onload after setting src
img.onload = function(){ console.log('I ran!'); };
Các Câu hỏi (s)
- chiều rộng và chiều cao hình ảnh nên được đúng ngay lập tức?
- Nếu canvas vẽ hoạt động ngay lập tức?
- Nếu cuộc gọi lại
onload
(được đặt sau khi đã thay đổi src) chưa?
Các thử nghiệm thực nghiệm
Tôi tạo ra một simple test page với mã tương tự. Trong Safari thử nghiệm đầu tiên của tôi, cả hai bằng cách mở trang HTML cục bộ (file:///
url) và tải nó từ máy chủ của tôi, cho thấy mọi thứ hoạt động: chiều cao và chiều rộng là chính xác, canvas vẽ hoạt động, và các onload
cũng cháy.
Trong Firefox v3.6 (OS X), tải trang sau khi khởi chạy trình duyệt cho thấy chiều cao/chiều rộng không chính xác ngay sau khi cài đặt, drawImage()
không thành công. (Tuy nhiên, trình xử lý onload
không kích hoạt.) Tải lại trang, hiển thị chiều rộng/chiều cao chính xác ngay sau khi cài đặt và drawImage()
hoạt động. Có vẻ như Firefox lưu trữ nội dung của URL dữ liệu dưới dạng hình ảnh và có sẵn ngay khi được sử dụng trong cùng một phiên.
Trong Chrome v8 (OS X), tôi thấy kết quả tương tự như trong Firefox: hình ảnh không có sẵn ngay lập tức, nhưng mất một thời gian để tải 'không đồng bộ' một cách không đồng bộ từ URL dữ liệu.
Ngoài bằng chứng thực nghiệm về những trình duyệt nào ở trên hoặc không hoạt động, tôi thực sự yêu các liên kết đến thông số kỹ thuật về cách hoạt động này. Cho đến nay, Google-fu của tôi vẫn chưa thực hiện được nhiệm vụ.
Playing Nó Safe
Đối với những người không hiểu tại sao ở trên có thể là nguy hiểm, hãy biết rằng bạn nên sử dụng hình ảnh như thế này để được an toàn:
// First create/find the image
var img = new Image;
// Then, set the onload handler
img.onload = function(){
// Use the for-sure-loaded img here
};
// THEN, set the src
img.src = '...';
Bạn chắc chắn cần đặt 'onload' trước khi đặt' src'. Nhưng nếu sự kiện tải đôi khi xảy ra trong chòm sao hiện tại, thì việc đặt URI "dữ liệu" thực sự là không đồng bộ - điều này sẽ làm tôi ngạc nhiên. Hấp dẫn! –
Không an toàn hơn để giả định rằng không, để bơm thời gian chờ và tiếp tục sau khi trình duyệt có cơ hội vẽ lại chính nó? –
@mP Vâng, chắc chắn là; Tôi đã chỉnh sửa câu hỏi của mình để làm rõ điều này trong 5 phút trước khi bình luận của bạn :) Tuy nhiên, điều này không làm mất hiệu lực câu hỏi. Giả sử rằng hành vi trong Chrome và FF được cho phép - không phải là lỗi - thì thực tế là nó rất quan trọng, để chơi nó an toàn. – Phrogz