Set animation loading khi background-image chưa được load

Chào các bạn, mình đang code 1 đoạn js hover zoom image và gặp 1 chút khó khăn như sau, mong các bạn giúp đỡ.

Cách hoạt động:

  • Khi hover chuột vào ảnh thì sẽ hiện hiệu ứng loading ( là hình vòng tròn ). Lúc này mình sẽ thêm 1 class là loading vào thẻ div.
  • Khi ảnh được tải xong HOÀN TOÀN thì hiệu ứng loading biến mất và hiển thị background là cái image vừa load được và xóa class loading kia đi.

Vấn đề mình gặp phải:

  • Mình có sử dụng Image() để bắt sự kiện ảnh onload nhưng khi load ảnh xong và set backgroundImage cho thẻ div, hiệu ứng loading đã kết thúc mà ảnh vẫn đang tải để hiện ra.
  • Trong một số trường hợp, khi kết thú hiệu ứng loading, backgroundImage chưa sẵn sàng để hiển thị thì sẽ xuất hiện 1 khoảng trắng ( các bạn có thể test bằng cách bật devtool hoặc bỏ cache và load lại là thấy )

Câu hỏi của mình:

  • Trong trường hợp của mình có event nào để bắt khi ảnh được tải xong HOÀN TOÀN
    backgroundImage đã sẵn sàng để hiển thị không?
  • Hoặc có cách nào để tối ưu nhất có thể cho trường hợp của mình không?
  • Mình thấy để time delay qua hàm setTimeout() thì không được ổn.

Đây là code của mình: https://codepen.io/notrealdev/pen/MWKXGxX

Vấn đề thì ngắn nhưng có thể mình trình bày hơi dài dòng, mong được các bạn hiểu được vấn đề mình muốn trình bày.

Cám ơn mọi người đã đọc bài.

Thật ra cách bắt sự kiện của bạn cơ bản là đúng tuy nhiên khi kết hợp với phần code còn lại hoàn toàn sai và không hề tận dụng được kết quả của việc bắt sự kiện.
Bạn tạo mới 1 image và set URL cho nó để bắt sự kiện ảnh đã được load về máy local hay chưa. Tuy nhiên ở đoạn code callback chính bạn lại đi set URL cũ để hiển thị ảnh background. Do đó lúc này trình duyệt sẽ phải load lại ảnh trên 1 lần nữa để hiển thị background của thẻ div. Như vậy việc bạn tạo 1 image rồi lắng nghe sự kiện load là gần như không có ý nghĩa gì cả. Với trường hợp bạn không bật clear cache thì sẽ khó thấy được độ trễ do lúc này có cache hỗ trợ. Tuy nhiên khi bật clear cache thì vấn đề hiện ra thấy rõ.
Giải pháp cho bạn:

  1. Sử dụng ajax load nội dung ảnh dưới dạng blob, convert blob thành dataURL và set link ảnh background bằng dataURL được sinh ra
  2. Convert image thành canvas, từ canvas convert thành dataURL. Set background cho div bằng dataURL đã sinh ra
6 Likes

Cám ơn bạn đã gợi ý cho mình, mình đã hoàn thành xong đoạn mã của mình trong dự án, mình có update code trên demo nhưng codepen.io reject vì lỗi bảo mật thì phải.
Tuy url dataUrl hơi dài nhưng chắc sẽ ít người để ý, cám ơn bạn :+1:t6:

Đúng rồi bạn. Đây là 1 tính năng để bảo vệ người dùng khỏi bị thu thập thông tin trái phép. Nói chung là sẽ xoay quanh vấn đề CORS trong trình duyệt hiện đại, để xử lí nó thì lại là 1 topic khác

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?