アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascript初心者です。

数日前にこちらで教えていただきまして、
画像をプリロードをして、画像がsetTimeoutで切り替わる動きをするスクリプト(任意の引数を与えた場所を処理する関数)ができたのですが、
IEで見たときにsetTimeoutのタイミングで毎回、画像読み込みがされているようなのですが(ブラウザの左下に文字が出てきます)
これを解消するにはどうすればいいでしょうか?

二箇所を同じ関数を使ってそれぞれ違う引数の付与でsetTimeoutのタイミングや読み込む画像や場所を変えています。


サンプル↓こちらに上げてあります。
http://foofoo77.web.fc2.com/imagechange/index6g. …

ソースは下記になります(上記と同一のものです)。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>一定時間で変わる画像</title>

<script type="text/javascript">
var animeImg = {};
//画像プリロード
function preLoad(ch) {
 var img;
 for (var i = 0; i < 4; i++) {
  img = new Image();
  img.src = "images/" + ch + i + ".gif"; // 0 ~ 3.gif
 }
 // 与えられた引数を使いカウンタ用プロパティを設定
 animeImg[ch] = { j: 0, fnum: 0 };
}

//時間制御

var wait = new Array( 3000, 500, 3000, 3000);
var wait2 = new Array( 500, 500, 500, 500);
//表示画像制御
function change(ch, time, number) {
 var obj = document.getElementById(ch);
 var data = animeImg[ch];
 obj.src = "images/" + ch + data.j + ".gif";
 data.j++;
var Num = number;
 if (data.j > Num) {
  data.j = 0;
 }
 if (data.fnum < Num) {
  data.fnum++;
 } else {
  data.fnum = 0;
 }

 var wtime = time[data.fnum];

 setTimeout(function() { change(ch, time, Num); }, wtime);
}

</script>
</head>

<body>
<img src="images/image0.gif" id="image">
<script type="text/javascript">
preLoad('image');
change('image',wait,3);
</script>

<img src="images/imageb0.gif" id="imageb">
<script type="text/javascript">
preLoad('imageb');
change('imageb',wait2,2);
</script>
</body>
</html>

A 回答 (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 とかがいらない。

こうやってかけば、つぎのひとが、おぶじぇくとしこうでかくかも?
と、ふってみる。
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

今回希望したとおりの動きになっているので参考にさせて頂きます。
ありがとうございました。

お礼日時:2011/02/12 15:21

ANo1 です。



やっぱりsrc を変えるとリロードしちゃうので、動的に読んだimg タグはキャッシュ用として事前に用意してある隠しタグ(display:none;属性)にinnerHTML して保存しておいて、次回はそれを使い回すのが良いと思います。
    • good
    • 0
この回答へのお礼

すいません、お礼が遅くなりました。
おっしゃるとおり、src属性を変えるとリロードしてしましますよね。
次回からは私のできる範囲で画像をdisplay:none;などにしてやりたいと思います。
ありがとうございました。

お礼日時:2011/02/12 15:16

ローカル環境でしかテストしてませんが…


確かに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>
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。
ご丁寧にスクリプトありがとうございます。

参考にさせて頂きます。

お礼日時:2011/02/12 15:18

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/
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

jQueryは今後使いたいと思っているので参考にさせて頂きます。
ありがとうございました。

お礼日時:2011/02/12 15:19

おぶじぇくとしこうというより、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]);
});

※おや!肝心のイメージプレロードが効いてないぞ。毎回、画像読み込みがされている。
だめだめだあ
    • good
    • 0

画像を全部HTML に記述しておいて、style="visibility:hidden;" とかにする。

んでそれぞれを表示したり非表示にしたりするのはどうですか?画像位置はposition:fixed; とかで重ねれますし。
    • good
    • 0
この回答へのお礼

おっしゃるとおりのやり方が一番簡単なやり方ですよね。

ありがとうございます。
今回は制約で使えなかったのですが、他でやるとき参考にさせていただきます。

ありがとうございました。

お礼日時:2011/02/12 15:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!