- ベストアンサー
一定時間で画像を変更するスクリプトの関数(IE)
- javascript初心者のため、一定時間で画像を切り替えるスクリプトの関数を作成しましたが、IEでの動作に問題があります。
- IEでsetTimeoutのタイミングで画像の読み込みがされてしまう問題について、解消方法を教えてください。
- 画像がプリロードされているにも関わらず、IEでの動作では毎回画像の読み込みが発生しています。どのようにすればこの問題を解決できるでしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
<!DOCTYPE html> <title>一定時間で変わる画像</title> <p><img src="images/image0.gif" id="image"></p> <p><img src="images/imageb0.gif" id="imageb"></p> <script> var makeFileList = function (start, end, path, name, imgType) { var result = []; for (; start <= end; start += 1) result.push (path + '/' + name + start + '.' + imgType); return result; }; var imageLoader = function (imageList) { var result = []; var i = 0; var I = imageList.length; var img; for (; i < I; i += 1) { img = new Image; img.src = imageList[i]; result.push (img); } return result; }; var Changer = function (target, image, interval) { var max = image.length; var cnt = 0; var view = target.ownerDocument./*@cc_on @if (1) parentWindow @else@*/ defaultView /*@end@*/; view.setTimeout (function () { target.src = image[cnt].src; cnt = (cnt + 1) % max; view.setTimeout (arguments.callee, interval[cnt] || 500); }, interval [0]); }; //_______________ Changer ( document.getElementById ('image'), imageLoader (makeFileList (0, 3, 'images', 'image', 'gif')), [ 3000, 500, 3000, 3000 ] ); Changer ( document.getElementById ('imageb'), imageLoader (makeFileList (0, 2, 'images', 'imageb', 'gif')), [ 500, 500, 500 ] ); </script> みじかく かけるものを ながくしてかいてみた。 Changer のなかが、いわゆるくろーじゃーになっているので、へんすうのほぞんがゆうこうです data.j とか data.form とかがいらない。 こうやってかけば、つぎのひとが、おぶじぇくとしこうでかくかも? と、ふってみる。
その他の回答 (5)
ANo1 です。 やっぱりsrc を変えるとリロードしちゃうので、動的に読んだimg タグはキャッシュ用として事前に用意してある隠しタグ(display:none;属性)にinnerHTML して保存しておいて、次回はそれを使い回すのが良いと思います。
お礼
すいません、お礼が遅くなりました。 おっしゃるとおり、src属性を変えるとリロードしてしましますよね。 次回からは私のできる範囲で画像をdisplay:none;などにしてやりたいと思います。 ありがとうございました。
- fujillin
- ベストアンサー率61% (1594/2576)
ローカル環境でしかテストしてませんが… 確かにIE(6)では毎回読んでるみたい。「ページのバージョンを確認しない」にしてもダメみたいですね。(他に設定があったかなぁ…) srcを書換えるから読みに行くのかと、nodeをcloneして要素ごと入替える方法にしてみたけれどダメ。 #1様の提案に近いけど、preloadの替わりにHTMLにpresetして、display属性で制御する方法にしてみたら、さずがに読みにはいかないみたい。 でも、こんなことする意味があるのかないのか… 多少、オブジェクトっぽくしてみましたが、長くなるばかり?(入力値のチェックは一切省略の手抜き。全角空白は半角に) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="ja"> <head><title>sample</title> <style> img { width:400px; height:400px; } </style> </head> <body> <div> <img src="images/image0.gif" id="image" alt=""> <img src="images/imageb0.gif" id="imageb" alt=""> </div> <script type="text/javascript"> <!-- var Changer = function(){ this.init.apply(this, arguments); } Changer.prototype = { start: function(){ if(this.max && !this.timerId) this.changer(); }, stop: function(){ if(this.timerId){ clearTimeout(this.timerId); this.timerId = null; } }, changer: function(){ var obj = this, fn = arguments.callee; obj.images[obj.counter++].style.display = "none"; obj.counter %= obj.max; obj.images[obj.counter].style.display = ""; obj.timerId = setTimeout(function(){ fn.call(obj); }, obj.parameter.intervals[obj.counter]); }, preSet: function(e, p){ var i, o, pnt = e.parentNode, img = e.cloneNode(false); img.removeAttribute("id"); img.style.display = "none"; this.images = []; for (i=p.start; i<=p.end; i++){ o = img.cloneNode(false); o.src = encodeURI(p.path + i + "." + p.extention); if (i != p.start) pnt.insertBefore(o, e); this.images.push(o); } e.src = this.images[0].src; this.images[0] = e; this.max = this.images.length; img = null; }, init: function(p){ if(!p || !p.id) return; var e = document.getElementById(p.id); if(!e || e.nodeName != "IMG") return this.parameter = p; // this.preLoad(p); this.preSet(e, p); this.counter = this.max -1; this.timerId = null; this.start(); } } new Changer({ id:"image", path:"images/image", extention:"gif", start:0, end:3, intervals:[3000, 500, 3000, 3000] }); //--> </script> </body> </html>
お礼
お礼が遅くなり申し訳ありません。 ご丁寧にスクリプトありがとうございます。 参考にさせて頂きます。
- yyr446
- ベストアンサー率65% (870/1330)
No.3の回答者です。 IEで毎回、画像読み込みがされているように見えたのは思い違いでした。 ちゃんと画像が存在すれば、何回もロードしません。 前のコードをもうちょっと整理して、オレオレの自動ファイル名リスト生成機能を使わなくても使えるようにして、さらにアニメーション効果もつけられるようにしたjQuery用プラグインにしました。↓に置いておきました。 https://gist.github.com/777400#comments ※動作のためには、途、jQuery本体 http://jquery.com/ と「jquery.timers.js」が必要です。 http://plugins.jquery.com/node/547/release ※イージング効果を使う場合は 「jquery.easing.1.3.js」も必要です。 http://gsgd.co.uk/sandbox/jquery/easing/
お礼
お礼が遅くなり申し訳ありません。 jQueryは今後使いたいと思っているので参考にさせて頂きます。 ありがとうございました。
- yyr446
- ベストアンサー率65% (870/1330)
おぶじぇくとしこうというより、jQueryのプラグインにしてみた。 ※イージング処理(jQuery)も後から追加できるかも (function($){ var methods = { init : function(options){ var settings = { start:0, end:0, path:null, name:null, imgType:null }; var imageSrcList = []; var imageList = []; if(options) $.extend(settings,options); for (; settings.start <= settings.end; settings.start += 1) imageSrcList.push (settings.path + '/' + settings.name + settings.start + '.' + settings.imgType); var I = imageSrcList.length; var img; for(var i=0;i<I;i+=1){ imageList.push($('<img src="' + imageSrcList[i] +'">')); } var $this = $(this); $(this).data("imageList",{ list:imageList }); }, change : function(interval,easing){ var max = this.data("imageList").list.length; var cnt = 0; var easing = easing; var $this = $(this); if(!easing){ window.setTimeout(function(){ $this.attr("src",$this.data("imageList").list[cnt].attr("src")); cnt = (cnt + 1) % max; window.setTimeout(arguments.callee,interval[cnt] || 500); },interval[0]); }else{ window.setTimeout(function(){ $this.attr("src",$this.data("imageList").list[cnt].attr("src")).animate( {opacity:"toggle"},"slow",easing); cnt = (cnt + 1) % max; window.setTimeout(arguments.callee,interval[cnt] || 500); },interval[0]); } } }; $.fn.Changer = function(method){ if(methods[method]){ return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); }else if(typeof method === 'object' || ! method){ return methods.init.apply(this,arguments); } else { $.error('Method ' + method + ' does not exist on jQuery.Changer' ); } }; })(jQuery); $(function(){ $('#image').Changer({start:0,end:3,path:'images',name:'image',imgType:'gif'}); $('#image').Changer("change",[3000,500,3000,3000]); }); ※おや!肝心のイメージプレロードが効いてないぞ。毎回、画像読み込みがされている。 だめだめだあ
画像を全部HTML に記述しておいて、style="visibility:hidden;" とかにする。んでそれぞれを表示したり非表示にしたりするのはどうですか?画像位置はposition:fixed; とかで重ねれますし。
お礼
おっしゃるとおりのやり方が一番簡単なやり方ですよね。 ありがとうございます。 今回は制約で使えなかったのですが、他でやるとき参考にさせていただきます。 ありがとうございました。
お礼
お礼が遅くなり申し訳ありません。 今回希望したとおりの動きになっているので参考にさせて頂きます。 ありがとうございました。