イナヅマTVログ

jQueryを使わないMouseEvent(click)処理とEvent委譲(delegate)

| 1件のコメント

MouseEvent(click)をjQueryを使わない処理(JavaScript)を試しました。

IEなどへのクロスブラウザにも対応することを目指します。
今持っている知識を活用して効率的に処理できるように工夫します。

MouseEvent処理する際に委譲(delegate)を使うと効率化が計れると聞き試してみます。

HTML

<div id="large"><img src="images/stocks/solarsystem.jpg" alt="" id="largeImg"></div>
 
<div id="thumbs">
	<ul id="thumbsCon">
		<li><a href="images/stocks/earth.jpg"><img src="images/thumb/earth.jpg" alt=""></a></li>
		<li><a href="images/stocks/jupiter.jpg"><img src="images/thumb/jupiter.jpg" alt=""></a></li>
		<li><a href="images/stocks/mars.jpg"><img src="images/thumb/mars.jpg" alt=""></a></li>
		<li><a href="images/stocks/mercury.jpg"><img src="images/thumb/mercury.jpg" alt=""></a></li>
		<li><a href="images/stocks/moon.jpg"><img src="images/thumb/moon.jpg" alt=""></a></li>
		<li><a href="images/stocks/neptune.jpg"><img src="images/thumb/neptune.jpg" alt=""></a></li>
		<li><a href="images/stocks/saturn.jpg"><img src="images/thumb/saturn.jpg" alt=""></a></li>
		<li><a href="images/stocks/solarsystem.jpg"><img src="images/thumb/solarsystem.jpg" alt=""></a></li>
		<li><a href="images/stocks/sun.jpg"><img src="images/thumb/sun.jpg" alt=""></a></li>
		<li><a href="images/stocks/uranus.jpg"><img src="images/thumb/uranus.jpg" alt=""></a></li>
		<li><a href="images/stocks/venus.jpg"><img src="images/thumb/venus.jpg" alt=""></a></li>
	</ul>
</div>

サムネイルをclickすると上部のid:largeImgの画像が切り替わるようにします。

JavaScript

;(function (window) {
	var document = window.document,
            $thumbs = document.getElementById('thumbs'),
            $largeImg = document.getElementById('largeImg')
	;
	function onClick (e) {
            var target, nodeName, a;
            if (typeof e === 'undefined') {
		e = window.event;
		target = e.srcElement;
            } else {
		e.preventDefault();
		e.stopPropagation();
		target = e.target;
            };
            nodeName = target.nodeName.toLowerCase();
            if (nodeName === 'img') {
		a = target.parentNode;
            } else if (nodeName === 'a') {
		a = target;
            } else {
		return false;
            };
            $largeImg.src = a.href;
 
            return false;
	};
	if (typeof $thumbs.addEventListener !== 'undefined') {
            $thumbs.addEventListener('click', onClick, true);
	} else {
            $thumbs.attachEvent('onclick', onClick);
	};
}(window));

コードを単純化するためにJavaScriptは<div id=”thumbs”>の下に書きました。
DOMの準備やWindowのロードを監視を省略するためです。

JavaScript
名前空間を汚染しないために以下のような構造で作成しています。

;(function (){<!-- code -->}());

無名関数を定義し実行させています。
実行時にGlobalなwindowインスタンスを引数にしています。

無名関数では引数名:windowで受け取り内部で使用しています。
引数名はwでも$wでも良かったのですが同名にしています。

documentインスタンスもローカル変数化するためにvar document = window.documentとしています。

委譲(delegate)
clickへのEvent Listner対象をaタグでなく<div id=”thumbs”>にしています。
複数のaタグそれぞれ個別に監視対象にする必要はありません。
Eventバブリングを利用し親のコンテナで処理をすれば効率化が計れます。

注意するのはイベントの発生場所がどこかをチェックして、処理を続けるか否かを判断しなければいけないことです。

Eventをリスナーする
EventはaddEventListenerかIEのattachEventを使いイベント・ハンドラを設定します。

Eventハンドラ
addEventListener
addEventListenerを使ったときはハンドラ引数へEventインスタンスが送られてきます。
EventインスタンスのtargetプロパティのnodeNameを調べるとEvent発生場所が分かります。

Eventの伝播を止めるためにpreventDefault, stopPropagationします。

attachEvent
attachEventを使った時は引数へEventインスタンスが送られてきません。
そのかわりwindow.eventが使えます。
window.eventにはtargetプロパティがありません、そのかわりsrcElementプロパティが使えます。
srcElementのnodeNameを調べるとEvent発生場所が分かります。

preventDefault, stopPropagationが使えないのでEventの伝播を止めるためにreturn falseで代用します。

【参考】
MDN: element.addEventListener
MDN: event.stopPropagation
MDN: event.preventDefault

msdn: attachEvent method

1件のコメント

  1. ピンバック: 超個人的メモ, JavaScript関連の投稿リンクをまとめておく « イナヅマTVログ

コメントを残す