2012-04-18 3 views
0

У меня небольшая проблема с функцией setTimeout.Функция тайм-аута jquery никогда не вызывалась на mouseenter mouseleave

$ (this) - каждый DOM-элемент с определенным классом.

Когда мышь входит в элемент, а затем оставьте его, нет проблем. Но когда мышь переносит элемент непосредственно в другой (в течение 500 мс тайм-аута), первый элемент (тот, с которого ушла мышь) никогда не исчезает.

Так что новый mouseenter-Event типа предотвращения времениOut для вызова функции. Без 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

Он смотрит на меня, как вы используете много глобальных переменных и при переходе в другой элемент, значение всех этих глобальных переменных получает изменилось. Функция таймаута ссылается на эти глобальные переменные, поэтому она не работает должным образом, когда они были изменены путем ввода другого элемента.

Он также выглядит так, как только вы вводите другой элемент, вы очищаете таймер, чтобы он не запускался, и поскольку это глобальный таймер, есть только один, чтобы вы убили таймер, который вы хотите запустить.

Для глобальной переменной задачи, поставить 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) 
Смежные вопросы