スポンサーサイト
2014.01.27 Monday
一定期間更新がないため広告を表示しています
- -
- -
- -
2012.10.06 Saturday
2012.10.05 Friday
第一引数 文字列又は関数オブジェクト
function test() { alert('test'); }; setTimeout(test, 1000);//1ms後実行 setTimeout(test(), 1000);//評価時に即実行 setTimeout('test()', 1000);//1ms後実行 setTimeout('test', 1000);//単なる文字列なので何も起こらない
第一引数が文字列の時evalされる。
引数を渡したいとき、
var str = 'str'; function test(arg) { alert(arg); }; setTimeout('test("' + str + '")', 1000); //一応可能 setTimeout(function(){test(str)}, 1000); //無名関数を渡せば問題無い
var arr = [1,2,3]; for(var i=0,len=arr.length;i<len;i++){ setTimeout(function() { console.log(arr[i]);//undefined×3 }, i * 1000); };
setTimeout内でarrにアクセスできていないのかと一見思った。 がiがブロックスコープの為このコンソールは全てarr[3]にアクセスし undefinedが返っている。
var arr = [1,2,3]; console.log(i);//undefined>条件式で定義されてるからエラーではない for(var i=0,len=arr.length;i<len;i++){ console.log(i);//0,1,2 setTimeout(function() { console.log(i);//3,3,3>ブロックスコープでは無い為 }, i * 1000); }; }; console.log(i);//3>条件式で3回インクリされた状態で残る var arr = [1,2,3]; for(var i=0,len=arr.length;i<len;i++){ (function(arg) { setTimeout(function() { console.log(arr[arg]);//1,2,3 }, arg * 1000); })(i); }; //クロージャにてスコープをキープ
forで回してDOM要素にアクセスしてイベントハンドリング。 参考までに画像を見込んだ順にフェードインするスクリプト。
<style type="text/css"> h1 { font-family: Helvetica, Arial; text-align: center; } #gallery { width: 95%; margin: 0 auto; padding: 5px; border: solid 1px #ccc; border-radius: 5px; } #gallery li { list-style-type: none; width: 200px; height: 200px; display: inline-block; background: url('load.gif') no-repeat center; } #gallery img { width: 200px; height: 200px; opacity: 0; } </style>
<h1>- gallery -</h1> <ul id="gallery"> <li><img src="1.png" /></li> <li><img src="2.png" /></li> <li><img src="3.png" /></li> <li><img src="4.png" /></li> <li><img src="5.png" /></li> <li><img src="6.png" /></li> <li><img src="7.png" /></li> <li><img src="8.png" /></li> <li><img src="9.png" /></li> <li><img src="10.png" /></li> <li><img src="11.png" /></li> <li><img src="12.png" /></li> </ul>
とりあえず、変数iをクロージャでキープ
onloadイベントの前に無名関数でスコープを作らないと
onloadが実行される時にはみんな同じiを参照してしまう、、、。
setTinerval内も無名関数のスコープで実行できる。
<script type="text/javascript"> var gallery = document.getElementById('gallery'); var elem = gallery.getElementsByTagName('img'); var timerId = []; var count = []; for(var i=0,len=elem.length;i<len;i++) { count[i] = 0; (function(arg) { elem[arg].onload = function() { timerId[arg] = setInterval(function(){fade(arg)}, 50); }; })(i); }; function fade(tar) { if(elem[tar].style.opacity >= 1) { clearInterval(timerId[tar]); } else { count[tar] += 0.1; elem[tar].style.opacity = count[tar]; }; }; </script>
こん度は頑張ってthisとか使ってみる。
そんで、ついでにmouseoverとかも追加してみる。
<script type="text/javascript"> function ImgObj(img) { var that = this; this.img = img; this.duration = 0.1; this.img.addEventListener('load', function() { that.fadeIn() }, false); this.img.addEventListener('mouseover', function() { that.fadeOut() }, false); this.img.addEventListener('mouseout', function() { that.fadeIn() }, false); }; ImgObj.prototype.fadeIn = function() { var that = this; if(this.fadeTimer) { clearInterval(this.fadeTimer); } else { this.opacity = this.img.style.opacity = 0; }; this.fadeTimer = setInterval(function() { that.chgOpacity(1) }, 50); }; ImgObj.prototype.fadeOut = function() { var that = this; if(this.fadeTimer) { clearInterval(this.fadeTimer); } else { this.opacity = this.img.style.opacity = 1; }; this.fadeTimer = setInterval(function() { that.chgOpacity(0) }, 50); }; ImgObj.prototype.chgOpacity = function(limit) { this.opacity = Math.round(this.opacity * 100) / 100; if(this.opacity == limit) { clearInterval(this.fadeTimer); } else { this.opacity += limit ? this.duration : -this.duration; this.img.style.opacity = this.opacity; }; }; var gallery = document.getElementById('gallery'); var elem = gallery.getElementsByTagName('img'); var imgObj = []; for(var i = 0, len = elem.length; i < len; i++) imgObj[i] = new ImgObj(elem[i]); </script>
クロージャなしでいけるのか?
しかしイベントリスナ部でthisを
使用するとそこはやはりそのイベント発生元のDOMを参照する。
setInterval内でのthisはwindowを参照する。
それでこのthisの参照が違うって聞くと、いよいよかっこよさげなapplyとか callが使えるの??って思って考えたけどよく理解していませんので 使い道が思いつきませんでした。
基本的にthisをローカル変数に代入してクロージャで参照するって感じでしょうか。
前から思ってたけどこういうイベントハンドリングみたいなのを クラスとか使う書き方が全くもってわからん。
なので我ながら
意味不明なコードになってます。
結局クロージャです。正直クロージャってのもあまり理解できていません。
なんか検索しようとするとメモリリークとかサジェストで出てくるし。
しっかり理解した方が良さそうさな。