🖨️
遅延読み込み(Lazy Loading)設定画像が印刷プレビューに表示されない問題について
問題
html
<button type="button" onclick="window.print()">印刷ボタン</button>
上記のように window.print()
メソッドのみで印刷ボタンを実装し、印刷を実行すると、loading="lazy"
属性が設定された遅延読み込み画像が印刷プレビューに表示されない問題がある。この現象はChromeやEdge、Safariなどで確認できるが、Firefoxでは問題なく表示される(Windows11で確認)。
ただし、Ctrl + P
(印刷のWindowsショートカット)で印刷プレビューを確認すると、問題なく遅延読み込み画像が表示される。
この挙動は下記のGithub Issuesでも報告されている。
解決方法(コード例)
印刷ボタン押下した際に、ページ内に存在する全ての画像を読み込むことで解決できる。
html
<button type="button" class="js-print">印刷ボタン</button>
js
/**
* 印刷ボタンがクリックされたときの処理
*/
const btn = document.querySelector(".js-print");
if (btn) {
btn.addEventListener("click", function () {
const images = document.querySelectorAll("img");
let imagesLoaded = 0;
const totalImages = images.length;
// ページに画像がない場合は、すぐに印刷を実行
if (totalImages === 0) {
window.print();
return;
}
/**
* 遅延読み込み画像の強制読み込み
*/
images.forEach((img) => {
// 遅延読み込み属性を削除して強制読み込み
if (img.loading === "lazy") {
img.loading = "eager";
}
// data-src属性が遅延読み込みに使用されている場合、srcに移動
if (img.dataset.src && !img.src) {
img.src = img.dataset.src;
}
});
/**
* 全ての画像の読み込み状態を確認し、全て読み込まれたら印刷を実行
*/
const handleImageProcessed = () => {
imagesLoaded++;
if (imagesLoaded === totalImages) {
window.print();
}
};
images.forEach((img) => {
if (img.complete) {
// 画像がすでに読み込まれている場合
handleImageProcessed();
} else {
// 画像が読み込まれていない場合、loadイベントを登録
img.addEventListener("load", handleImageProcessed);
// エラーが発生した場合のイベントを登録
img.addEventListener("error", handleImageProcessed);
}
});
});
}
Discussion