JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2017年10月 / 09月<< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >>11月

アクセスランキング

[ジャンルランキング]
コンピュータ
265位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
35位
アクセスランキングを見る>>

ロールオーバー処理の読み込み遅延

久々にWEB系の記事です。

最近、某カメラメーカー、P社のサイトを見たのですが、画像に設定されたリンクをクリックしようとマウスポインタを載せると画像が消えました。原因は、その画像(リンク)にロールオーバー処理が施されていることだということはすぐにわかりましたが、ユーザー体験の面ではあまり良いものとは言えませんね。

というわけで、「ロールオーバー時に画像が消える」という現象の解決策についての記事を書くことにしました。

どのような条件でこの現象が起こるのかということですが、「画像のキャッシュがあるかないか」がポイントです。あらかじめ画像を読み込んでおけば、画像が消えることはないようです。

その場合、どのタイミングで画像を読み込むか、ということが重要となります。

続きは以下からどうぞ。
more...

以下、Firefox18とIE10による検証結果です。

なお、ページ読み込み時は画像1(pic1.bmp)、マウスオーバー時には画像2(pic2.bmp)が表示されるものとします。

1.事前のキャッシュ読み込みなし、mouseover,mouseoutイベント時にsrc属性を変更
ホームページビルダーやDreamweaver何かでも使われる処理です。

表示例

<style type="text/css">
img a{
    border-width: 0px;
}

#ro_pic{
    width: 800px;
    height: 317px;
}
</style>
<script type="text/javascript">
window.onload = function(){
    var ro = document.getElementById("ro_pic");
    ro.onmouseover = function(e){
        ro.src = "pic2.bmp";
    }
    ro.onmouseout = function(e){
        ro.src = "pic1.bmp";
    }
}
</script>
</head>
<body>

<a href="roll.html">
<img src="pic1.bmp" id="ro_pic">
</a>

</body>

この場合、マウスオーバー時に画像の読み込みが完了していないと、画像1が表示されたままとなります。(画像2の読み込みが終わり次第、表示が切り替わります。)

グラフの二回目の波が、ロールオーバー時の画像読み込み開始を示しています。

r1.png


2.事前のキャッシュ読み込みなし、hover時にbackground-imageを変更
JavaScriptを利用せずにロールオーバー処理を実装する場合に利用されます。

表示例

<style type="text/css">
img a{
    border-width: 0px;
}
#ro_a{
    background-image: url("pic1.bmp");
    display: block;
    width: 800px;
    height: 317px;
}
#ro_a:hover{
    background-image: url("pic2.bmp");
}

</style>
</head>
<body>
<a href="roll.html" id="ro_a"></a>
</body>

この場合、ロールオーバー時に画像の読み込みが完了していないと、一時的に背景が真っ白になります。(例のP社のサイトでの現象と同じものです。)

ネットワーク利用の波形も同様です。
r3.png


3.img要素を利用して事前にキャッシュ、hover時にbackground-imageを変更
2番のコードに、非表示でpic1.bmpを読み込むようimg要素を追加したものです。

表示例

<html>
<head>
<style type="text/css">
img a{
    border-width: 0px;
}
#ro_a{
    background-image: url("pic1.bmp");
    display: block;
    width: 800px;
    height: 317px;
}
#ro_a:hover{
    background-image: url("pic2.bmp");
}

</style>
</head>
<body>
<img src="pic2.bmp" style="display: none;">
<a href="roll.html" id="ro_a"></a>
</body>
</html>


この場合、ロールオーバー時に画像の読み込みが完了していないと表示が消えてしまうという点は同じですが、非同期的に画像を先読みしているので、画像の読み込みが完了していれば、表示が消えるという状態にはなりません。

r6.png


4.img要素を利用して事前にキャッシュ、mouseover,mouseoutイベント時にsrc属性を変更
3番と同じように、img要素を追加して先読みを行っています。

表示例

<head>
<style type="text/css">
img a{
    border-width: 0px;
}

#ro_pic{
    width: 800px;
    height: 317px;
}
</style>
<script type="text/javascript">
window.onload = function(){
    var ro = document.getElementById("ro_pic");
    ro.onmouseover = function(e){
        ro.src = "pic2.bmp";
    }
    ro.onmouseout = function(e){
        ro.src = "pic1.bmp";
    }
}
</script>
</head>
<body>
<img src="pic2.bmp" style="display: none;">
<a href="roll.html">
<img src="pic1.bmp" id="ro_pic">
</a>

</body>


こちらの場合、ロールオーバー時に画像が消えるということもないので、3番よりも適しているといえます。

r5.png



その他、画像をJSで読み込んでおいてappendChild,removeChildを行うという方法も試しましたが、4番の例と特に変わりはありませんでした。

まとめ
通常のロールオーバー処理に画像の先読みを行う処理を追加するのみで対応が可能です。

<head>
<script type="text/javascript">

var setRollOver = function(__el,__pic1,__pic2){
    var __imgEl1 = document.createElement("img");
    var __imgEl2 = document.createElement("img");
    __imgEl1.src = __pic1; __imgEl2.src = __pic2;
    __el.onmouseover = function(){
        this.src = __pic2;
    };__el.onmouseout = function(){
        this.src = __pic1;
    };
}


window.onload = function(){
    setRollOver(document.getElementById("pic"),"pic1.bmp","pic2.bmp");
}

</script>
</head>
<body>
<a href="ans.html"><img src="pic1.bmp" id="pic"></a>
</body>


※ブラウザ・対象の要素によりイベント伝播の仕様が異なるので、attachEvent/addEventListenerはあえて利用していません。


久々に長い記事になってしまいました。

#Firefoxのバージョンを調べたらもう18で… 前々から思っていますが、サイクルはやいですね。
 


 
   CSS    TB(0)    CM(0)    EDIT    ページ↑

コメント投稿


 管理者だけに表示

コメント

トラックバック

この記事へのトラックバック:

プロフィール

JDB Luigi

Author:JDB Luigi
どこにでもいるようなありふれた人間・・・という訳でもなく、かと言って怪しい宗教を信仰する変人という訳でも無い。

基本的に掲載しているコード等は煮ていただいても焼いていただいても結構ですが、利用は自己責任にてお願いいします。
また、バグ・アドバイス等もしあればよろしくお願いします。

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。