2012-04-18 12 views
0

setTimeout-functionに少し問題があります。jquery timeout-functionがmouseenter mouseleaveで呼び出されない

$(this)は、特定のクラスを持つすべてのDOM要素です。

マウスがelememtに入ってから離しても問題ありません。しかし、マウスが要素を別の要素に直接渡すと(500msのタイムアウト時間内に)、最初の要素(その1つはマウスが左に残っています)がフェードアウトすることはありません。

したがって、新しいmouseenter-eventは、timeOutが関数を呼び出すのを防ぎます。 setTimeout-wrapperがなければ、すべて正常に動作しています。

ここに私のコードです:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']); 


/** 
* manage mouseenter events 
*/ 
mouseenterManager: function() { 

    clearTimeout(timer); 

    //create toolbar, if no toolbar is in dom 
    if ($(this).data("layouter").toolbar == undefined) { 

     //get bottom center of this element 
     pos_left = ($(this).width()/2) + $(this).offset().left; 
     pos_top = $(this).height() + $(this).offset().top; 

     //create toolbar element 
     toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>'); 

     //bind this element to toolbar 
     toolbar.data("layouter", { 
      parent: $(this), 
     }); 

     //bind toolbar to this element 
     data = $(this).data("layouter"); 
     data.toolbar = toolbar; 
     $(this).data("layouter", data); 

     //bind this element to toolbar 
     data = toolbar.data("layouter"); 
     data.parent = $(this); 
     toolbar.data("layouter", data); 

     element = $(this); 
     toolbar.mouseleave(function() { 

      toolbar = $(this); 
      timer = setTimeout(function() { 
       if (!toolbar.is(":hover") && !element.is(":hover")) { 

        toolbar.fadeOut("fast", function() { 
         $(this).remove(); 
        }); 

        data = element.data("layouter"); 
        data.toolbar = undefined; 
        element.data("layouter", data); 
       } 
      }, 500); 
     }); 

     //display the toolbar 
     $("body").append(toolbar); 
     toolbar.fadeIn("fast"); 
    } 
}, 


/** 
* manage mouseleave events 
*/ 
mouseleaveManager: function() { 

    toolbar = $(this).data("layouter").toolbar; 
    element = $(this); 
    if (toolbar != undefined) { 
     timer = setTimeout(function() { 
      if (!toolbar.is(":hover")) { 

       toolbar.fadeOut("fast", function() { 
        $(this).remove(); 
       }); 

       data = element.data("layouter"); 
       data.toolbar = undefined; 
       element.data("layouter", data); 
      } 
     }, 500); 
    } 
}, 

};​ 

任意のアイデア?

ありがとうございました!

答えて

0

それは私には見えます。あなたのタイムアウト関数はそれらのグローバル変数を参照していますので、別の要素を入力して変更したときに正しく機能しません。

また、別の要素を入力するとすぐに私のように見えます。タイマーをクリアして実行しないようにします。グローバルタイマーなので、起動させるタイマーを1つだけ殺しました。グローバル変数の問題については

は、このような地域のあるべきすべての変数の前にvarを置く:タイマーの問題については

var toolbar = $(this).data("layouter").toolbar; 
var element = $(this); 

//get bottom center of this element 
var pos_left = ($(this).width()/2) + $(this).offset().left; 
var pos_top = $(this).height() + $(this).offset().top; 

を、それはあなたのように私に見えます単一のグローバルタイマーを持つ必要はありませんが、各要素にはタイマーが必要です。それは少し複雑です。何かを実行してテストすることができなければ、これが他の変更なしに動作するかどうかは確かではありませんが、ローカルになるように変数を修正し、タイマーを各要素に対してローカルにする正しいステップのステップです:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']); 


/** 
* manage mouseenter events 
*/ 
mouseenterManager: function() { 

    var self = $(this); 
    var timer = self.data("timer"); 
    if (timer) { 
     clearTimeout(timer); 
    } 

    //create toolbar, if no toolbar is in dom 
    if (self.data("layouter").toolbar == undefined) { 

     //get bottom center of this element 
     var pos_left = ($(this).width()/2) + $(this).offset().left; 
     var pos_top = $(this).height() + $(this).offset().top; 

     //create toolbar element 
     var toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>'); 

     //bind this element to toolbar 
     toolbar.data("layouter", { 
      parent: self, 
     }); 

     //bind toolbar to this element 
     var data = self.data("layouter"); 
     data.toolbar = toolbar; 
     self.data("layouter", data); 

     //bind this element to toolbar 
     data = toolbar.data("layouter"); 
     data.parent = self; 
     toolbar.data("layouter", data); 

     var element = self; 
     toolbar.mouseleave(function() { 

      toolbar = self; 
      timer = setTimeout(function() { 
       self.data("timer", null); 
       if (!toolbar.is(":hover") && !element.is(":hover")) { 

        toolbar.fadeOut("fast", function() { 
         $(this).remove(); 
        }); 

        data = element.data("layouter"); 
        data.toolbar = undefined; 
        element.data("layouter", data); 
       } 
      }, 500); 
      self.data("timer", timer); 
     }); 

     //display the toolbar 
     $("body").append(toolbar); 
     toolbar.fadeIn("fast"); 
    } 
}, 


/** 
* manage mouseleave events 
*/ 
mouseleaveManager: function() { 

    var toolbar = $(this).data("layouter").toolbar; 
    var element = $(this); 
    var timer = element.data("timer"); 
    if (toolbar != undefined && !timer) { 
     timer = setTimeout(function() { 
      element.data("timer", null); 
      if (!toolbar.is(":hover")) { 

       toolbar.fadeOut("fast", function() { 
        $(this).remove(); 
       }); 

       var data = element.data("layouter"); 
       data.toolbar = undefined; 
       element.data("layouter", data); 
      } 
     }, 500); 
     element.data("timer", timer); 
    } 
}, 

};​ 
+0

ありがとうございます!これは単純なグローバル/ローカルの問題でした。 "var"を使ってローカル変数をローカルとしてマークする必要があるのは私だけです。 –

0

編集したい要素をタイマーの機能に渡します。例えば

:あなたはグローバル変数の多くを使用していて、別の要素に入る際に、これらすべてのグローバル変数の値が変更されますよう

timer = setTimeout(function(toolbar, element) { 
     if (!toolbar.is(":hover")) { 

      toolbar.fadeOut("fast", function() { 
       toolbar.remove(); 
      }); 

      data = element.data("layouter"); 
      data.toolbar = undefined; 
      element.data("layouter", data); 
     } 
    }, 500)