2014-09-11 9 views
1

Я пытаюсь создать код, который, когда вы наведете диапазон в течение нескольких секунд, появится окно, и если вы держите мышь на коробке, он будет стоять на месте, не затухая снова. Пример кода это один:Почему второй раз, когда я наводил элемент, он исчезает?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title>I'm a pathetic programmer please don't flame me</title> 
    <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script> 
    <script type="text/javascript"> 
     $(function() { 
      var b = 1000; 
      var c = $('#box'); 
      var d = function(a) { 
       if (a) { 
        c.fadeOut(500) 
       } else { 
        c.fadeIn(500) 
       } 
      }; 
      $('span').mouseenter(function() { 
       e = setTimeout(function() { 
        d() 
       }, b); 
       $(this).mouseleave(function() { 
        typeof e != 'undefined' && clearTimeout(e); 
        f = setTimeout(function() { 
         d(1) 
        }, 300) 
       }) 
      }); 
      c.mouseenter(function() { 
       clearTimeout(f); 
       typeof g != 'undefined' && clearTimeout(g) 
      }).mouseleave(function() { 
       g = setTimeout(function() { 
        d(1) 
       }, 300) 
      }) 
     }); 
    </script> 
    <style type="text/css" media="screen"> 
     #box { 
      display: none; 
      width: 100px; 
      height: 100px; 
      background-color: lightblue; 
     } 
    </style> 
</head> 
<body> 
<span>HOVER ME</span> 
<div id="box"></div> 
</body> 
</html> 

Edit: JS скрипку для живого теста: http://jsfiddle.net/2ogcp9tm/

Проблема заключается в том, что код работает отлично в первый раз, когда я запустить его, но если я парить промежуток для второй раз, и я пытаюсь поместить мою мышь в синюю коробку, она все равно исчезает.

Почему это происходит?

+0

Пожалуйста, не оставляйте уменьшенная с ode - использовать значащие имена переменных, а не a, b, c, ... – Barmar

+0

@Barmar te original var были наихудшими, поэтому я сделал это, потому что это более понятно, чем использовать переменные, написанные на иностранном языке. – Flerex

+0

Хорошая точка, это тоже очень раздражает. :) Но иногда мы можем понять их, в то время как a, b, c, совершенно сбивает с толку. – Barmar

ответ

2

Каждый раз, когда вы вводите span, вы связываете обработчик mouseleave для этого диапазона. Поэтому, если вы вводите диапазон несколько раз, когда вы его покидаете, вы будете запускать обработчик mouseleave несколько раз. Каждый из них вызовет setTimeout(), но f будет установлен только на последний. Поэтому, когда вы позже делаете clearTimeout(f), он очищает только один из них, остальные продолжают работать.

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

1

Держись .mouseleave() обработчика событий каждый раз, когда mouseenter запускается для span, создавая несколько обработчиков событий для того же события, что приводит к срабатыванию всех этим обработчиков, что делает mouseleave логики некорректной (установки нескольких таймов-аутов и переписывание f переменных).

.mouseleave() следует переписать в чем-то вроде этого:

var e; 

$('span').mouseenter(function() { 
    e = setTimeout(function() { 
     d() 
    }, b); 
}); 

$('span').mouseleave(function() { 
    typeof e != 'undefined' && clearTimeout(e); 
    f = setTimeout(function() { 
     d(1) 
    }, 300) 
}); 

Updated fiddle.

0
$(function() { 
     var b = 1000; 
     var c = $('#box'); 
     var d = function(a) { 
      if (a) { 
       c.fadeOut(500) 
      } else { 
       c.fadeIn(500) 
      } 
     }; 
     $('span').mouseenter(function() { 
      e = setTimeout(function() { 
       d() 
      }, b); 
     }); 
      $('#box').mouseenter(function() { 
      e = setTimeout(function() { 
       d() 
      }, b); 
      $(this).mouseleave(function() { 
       typeof e != 'undefined' && clearTimeout(e); 
       f = setTimeout(function() { 
        d(1) 
       }, 300) 
      }) 
     }); 
     c.mouseenter(function() { 
      clearTimeout(f); 
      typeof g != 'undefined' && clearTimeout(g) 
     }).mouseleave(function() { 
      g = setTimeout(function() { 
       d(1) 
      }, 300) 
     }) 
    }); 

И вот JSFiddle `http://jsfiddle.net/2ogcp9tm/3/

+0

У вас было событие, при котором поле будет исчезать на 'mouseleave' из' span'. Поскольку 'div' является совершенно другим сущностью, ввод этого' div' будет вызывать функцию «mouseleave». В обновлении, которое я только что опубликовал, «mouseleave» вместо этого привязывается к 'div'. Таким образом, поле показывает, когда вы навешаете 'span' и не уходите снова, пока не будете' mouseleave' 'div' –

1

Попробуйте это: click here for jsfiddle working code

Старый Код:

 $('span').mouseenter(function() { 
      e = setTimeout(function() { 
       d() 
      }, b); 
      $(this).mouseleave(function() { 
       typeof e != 'undefined' && clearTimeout(e); 
       f = setTimeout(function() { 
        d(1) 
       }, 300) 
      }) 
     }); 

Новый код:

 $('span').mouseenter(function() { 
      e = setTimeout(function() { 
       d() 
      }, b); 
     }).mouseleave(function() { 
      typeof e != 'undefined' && clearTimeout(e); 
      f = setTimeout(function() { 
       d(1) 
      }, 300) 
     }); 
Смежные вопросы