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> 

편집 : 라이브 테스트 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

당신은 (여러 시간 제한을 설정하고 f 변수를 재 작성)마다 mouseenter가 잘못 mouseleave 논리를 만들고, 모든 핸들러를 트리거 결과 동일한 이벤트에 대한 여러 이벤트 핸들러를 생성, span에 대한 트리거 .mouseleave() 이벤트 핸들러를 끊습니다.

.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

당신은'span'에서'mouseleave'에 상자가 사라지게하는 이벤트가있었습니다. 'div'는 완전히 다른 엔티티이므로,'div'를 입력하면'mouseleave' 함수가 트리거됩니다. 방금 게시 한 업데이트에서'mouseleave'는 대신'div'에 바인딩됩니다. 이렇게하면'span '을 가리키면'div'를 mouseleave 할 때까지 상자가 사라집니다. –

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) 
     }); 
관련 문제