- 2007-03-16 (金) 4:50
- programing | javascript | 日記
2 users
0 user
0 user
久々のエントリーです。
最近はまったく忙しくて、全然勉強する時間もありゃしません。
弊社の人が作ったJavaScriptでトグル処理をするソースコードがメールで流れてきて それに触発されて、自分もいろいろ書いてみて、社内でシェアしたものをうpします。
まるごとJavaScriptを見ていて、クロージャっていいよね。という気分だったので クロージャをおさらいしてみました。 トグル処理の様々な実装方法テスト in JavaScript
最終的なソースコードはこんな感じになったよ。
/**
* オブジェクトを継承する(Objectを汚染拡張 from prototype.js)
* @param destination 拡張されるオブジェクト
* @param source 雛形オブジェクト
*/
Object.mixin = function( destination, source ){
for (property in source)
destination[property] = source[property];
return destination;
}
/**
* トグル可能な要素を表すクラス
*/
var TogglableElement = function(){};
TogglableElement.prototype = {
flag:true,
resultTarget:undefined,
toggle:function(){
this.flag = !this.flag;
},
update:function(){
this.resultTarget.innerHTML = ( this.flag ) ? 'ON' : 'OFF';
},
onmouseup:function(){
this.toggle();
this.update();
}
};
/**
* 初期化
* イベントハンドラはHTML内ではなく、スクリプト内で定義
*/
function init(){
/* オブジェクト拡張方式 */
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
// ボタン要素をトグラブルオブジェクトに拡張する
Object.mixin( btn1, TogglableElement.prototype );
Object.mixin( btn2, TogglableElement.prototype );
// 出力先を定義する
btn1.resultTarget = document.getElementById('result1');
btn2.resultTarget = document.getElementById('result2');
/* クロージャ渡し方式 */
document.getElementById('btn3').onmouseup = getToggleClosure( document.getElementById('result3') );
document.getElementById('btn4').onmouseup = getToggleClosure( document.getElementById('result4') );
/* ソースコードの表示トグル */
document.getElementById('viewsource-a').onclick = getToggleClosure2( document.getElementById('sourcecode-a'), viewSourceCode );
document.getElementById('viewsource-b').onclick = getToggleClosure2( document.getElementById('sourcecode-b'), viewSourceCode );
document.getElementById('viewsource-c').onclick = getToggleClosure2( document.getElementById('sourcecode-c'), viewSourceCode );
}
/**
* トグル処理&DOM操作のクロージャ関数を返す
* 1つの関数を各所で使い回せるようにクロージャ化する
* @param target HTMLElement 内容を書き換えるHTML要素
*/
function getToggleClosure( target ){
var flag = true; // フラグ。レキシカルスコープ内に保持
var target = target; // ターゲット。レキシカルスコープ内に保持
return function(){
flag = !flag; // フラグを逆転
target.innerHTML = ( flag ) ? 'ON' : 'OFF'; // flag==trueならON
};
}
function getToggleClosure2( target, callback ){
var flag = true;
var target = target;
var callback = callback
return function(){
flag = !flag; // フラグを逆転
callback.apply( this, [ target, flag ] );
};
}
function viewSourceCode( target, flag ){
this.innerHTML = ( flag )? 'ソースコードを表示する' : 'ソースコードを隠す';
target.style.display = ( flag )? 'none' : 'block';
}
/**
* window.onloadにリスナーを貼る
*/
if( /msie/.test(navigator.userAgent.toLowerCase()) )
window.attachEvent( 'onload', init );
else
window.addEventListener( 'load', init, true );
* オブジェクトを継承する(Objectを汚染拡張 from prototype.js)
* @param destination 拡張されるオブジェクト
* @param source 雛形オブジェクト
*/
Object.mixin = function( destination, source ){
for (property in source)
destination[property] = source[property];
return destination;
}
/**
* トグル可能な要素を表すクラス
*/
var TogglableElement = function(){};
TogglableElement.prototype = {
flag:true,
resultTarget:undefined,
toggle:function(){
this.flag = !this.flag;
},
update:function(){
this.resultTarget.innerHTML = ( this.flag ) ? 'ON' : 'OFF';
},
onmouseup:function(){
this.toggle();
this.update();
}
};
/**
* 初期化
* イベントハンドラはHTML内ではなく、スクリプト内で定義
*/
function init(){
/* オブジェクト拡張方式 */
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
// ボタン要素をトグラブルオブジェクトに拡張する
Object.mixin( btn1, TogglableElement.prototype );
Object.mixin( btn2, TogglableElement.prototype );
// 出力先を定義する
btn1.resultTarget = document.getElementById('result1');
btn2.resultTarget = document.getElementById('result2');
/* クロージャ渡し方式 */
document.getElementById('btn3').onmouseup = getToggleClosure( document.getElementById('result3') );
document.getElementById('btn4').onmouseup = getToggleClosure( document.getElementById('result4') );
/* ソースコードの表示トグル */
document.getElementById('viewsource-a').onclick = getToggleClosure2( document.getElementById('sourcecode-a'), viewSourceCode );
document.getElementById('viewsource-b').onclick = getToggleClosure2( document.getElementById('sourcecode-b'), viewSourceCode );
document.getElementById('viewsource-c').onclick = getToggleClosure2( document.getElementById('sourcecode-c'), viewSourceCode );
}
/**
* トグル処理&DOM操作のクロージャ関数を返す
* 1つの関数を各所で使い回せるようにクロージャ化する
* @param target HTMLElement 内容を書き換えるHTML要素
*/
function getToggleClosure( target ){
var flag = true; // フラグ。レキシカルスコープ内に保持
var target = target; // ターゲット。レキシカルスコープ内に保持
return function(){
flag = !flag; // フラグを逆転
target.innerHTML = ( flag ) ? 'ON' : 'OFF'; // flag==trueならON
};
}
function getToggleClosure2( target, callback ){
var flag = true;
var target = target;
var callback = callback
return function(){
flag = !flag; // フラグを逆転
callback.apply( this, [ target, flag ] );
};
}
function viewSourceCode( target, flag ){
this.innerHTML = ( flag )? 'ソースコードを表示する' : 'ソースコードを隠す';
target.style.display = ( flag )? 'none' : 'block';
}
/**
* window.onloadにリスナーを貼る
*/
if( /msie/.test(navigator.userAgent.toLowerCase()) )
window.attachEvent( 'onload', init );
else
window.addEventListener( 'load', init, true );
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://www.func09.com/wordpress/archives/125/trackback
- Listed below are links to weblogs that reference
- JavaScript、クロージャをおさらいしてみる from func09