hover() は mouseenter と mouseleave を同時にセットする
http://docs.jquery.com/Events/hover の引数の名前付けを見て、hover は mouseover と mouseout を同時に指定するものだと思っていたが違うらしい。
jquery-1.2.6.js の 2278 行付近
hover: function(fnOver, fnOut) {
return this.bind(‘mouseenter’, fnOver).bind(‘mouseleave’, fnOut); },
とあるように mouseenter と mouseleave に対して指定するものである。
over/outと enter/leave の違いは、http://docs.jquery.com/Events/mouseover の Demo みるとよくわかる。
ある領域 A にカーソルが載ったときに、領域 A 内に動的にブロック B を表示するという処理を次のようなに作っていた。
http://tilfin.googlepages.com/overout.html
|
|
しかし、これだと表示されたブロック B にカーソルが載ったとき、A の mouseout が発生するためちらつきが起こってしまう(これは Firefox のときで IE ではちらつきではなく消えたままになった)。
http://tilfin.googlepages.com/enterleave.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="content-script-type" content="text/javascript">
<script src="jquery-1.2.6.js"></script>
<title>jquery mouseenter / mouseleave</title>
<style type="text/css"><!--
#A {
color:#fff;
background-color:blue;
border:1px solid #000;
width:300px;
height:200px;
position:relative;
}
#B {
color:#fff;
background-color:red;
border:1px solid #000;
display:none;
width:200px;
height:100px;
position:absolute;
bottom:0;
right:0;
}
#debug p {
margin:0;
line-height:110%;
font-size:9pt;
}
//--></style>
<script><!--
$(document).ready(function(){
$("#A").hover(function(){
$("#debug").append("<p>A: mouseenter</p>");
$("#B").appendTo(this).show();
}, function(){
$("#debug").append("<p>A: mouseleave</p>");
$("#B").hide().appendTo(document.body);
});
/*
$("#A")
.bind("mouseenter", function(){
$("#debug").append("<p>A: mouseenter</p>");
$("#B").appendTo(this).show();
})
.bind("mouseleave", function(){
$("#debug").append("<p>A: mouseleave</p>");
$("#B").hide().appendTo(document.body);
});
*/
});
//--></script>
</head>
<body>
<div id="A">A</div>
<div id="B">B</div>
<div id="debug"></div>
</body>
</html>
として hover (mouseenter/mouseleave) を使うとうまくいった。
これは jQuery のソースをみると下記のようにサブ要素上にまだあるかイベント内でフックして判定しているからである。
jQuery.event.special.mouseleave.handler
|
|
ちなみにこのような動的な方法ではなく、元々
と書いてある場合は、上記の例(over/out も enter/leave)どちらでも動作する。
hover を unbind する方法
hover はイベントタイプとして存在するわけではないので、 $("#A").unbind("hover") とは書けない。
$("#A").unbind("mouseover").unbind("mouseout");
とするのも駄目である。これだと前述のように、mouseenter と mouseleave からイベントバインドされているため上記の jQuery.event.special.mouseleave.handler がフックされたまま残ってしまうからだ。
$("#A").unbind("mouseenter").unbind("mouseleave");
とするのが正しい。