読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

DOM mouseoutイベントをはまらないように使う

子要素を持つ要素にonmouseout属性を追加して何か処理しようとすると、ハマります。マウスカーソルが子要素に入ると、onmouseout属性を追加した要素から出たとみなされるからです。
子要素にもonmouseout属性を追加するとさらに話がややこしくなります。バブリング万歳です。


Internet Explorerならonmouseleave属性を使うと期待通りの動作をしてくれますが、そうでない場合、子要素に入った時のイベントをキャンセルする必要があります。
ググると、意外と皆さん対処療法で対応されているみたいでしたが、きれいにコーディングされていた方がいました。

onMouseOut fix on nested elements – JavaScript

/*********************************************************************
 * No onMouseOut event if the mouse pointer hovers a child element 
 * *** Please do not remove this header. ***
 * This code is working on my IE7, IE6, FireFox, Opera and Safari
 * 
 * Usage: 
 * <div onMouseOut="fixOnMouseOut(this, event, 'JavaScript Code');"> 
 *		So many childs 
 *	</div>
 *
 * @Author Hamid Alipour Codehead @ webmaster-forums.code-head.com		
**/
function is_child_of(parent, child) {
	if( child != null ) {			
		while( child.parentNode ) {
			if( (child = child.parentNode) == parent ) {
				return true;
			}
		}
	}
	return false;
}
function fixOnMouseOut(element, event, JavaScript_code) {
	var current_mouse_target = null;
	if( event.toElement ) {				
		current_mouse_target 			 = event.toElement;
	} else if( event.relatedTarget ) {				
		current_mouse_target 			 = event.relatedTarget;
	}
	if( !is_child_of(element, current_mouse_target) && element != current_mouse_target ) {
		eval(JavaScript_code);
	}
}
/*********************************************************************/


おかげさまでうまく問題を回避できました。
JavaScript_codeのところがテキストで、引数が取れないクロージャのような形になるので、ハンドラ渡す形に変更して使いました。