Spring MVC

springmvc.egloos.com


포토로그


2012/03/28 18:51

jQuery 애니메이션의 중복문제 해결! jQuery

jQuery는 매우 짧은 코드만으로도 휼륭한 애니메이션 효과를 낼 수 있다는 장점이 있다. 이러한 일이 가능해진 이유는 jQuery가 굉장히 우수한 방법을 통하여 자바스크립트 기능을 리팩토링하였기 때문인데 개인적으로 jQuery의 소스를 통해 자바스크립트 리팩토링 과정을 공부하면 매우 유익할 듯 싶다. (물론 그 길고긴 소스를 직접 해독해야 한다는 사실은 곤욕이지만…)

오늘 우리는 jQuery에서 발생하는 애니메이션 중복문제에 대한 해결책을 알아보도록 할 것이다. 우선 다음과 같은 코드를 작성해 보도록 하자.

<div class="btn">
<span style="border: 1px solid #000">클릭하세요!</span>
<div class="hideMenu" style="display: none">
<ul>
<li>숨겨진 메뉴1
<li>숨겨진 메뉴2
</ul>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript"></script>
<div class="btn">
<span style="border: 1px solid #000">클릭하세요!</span>
<div class="hideMenu" style="display: none">
<ul>
<li>숨겨진 메뉴1
<li>숨겨진 메뉴2
</ul>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript"></script>
<script>
$('.btn').bind({
mouseenter: function() {
$('.hideMenu').slideDown();
},
mouseleave: function() {
$('.hideMenu').slideUp();
}
});
</script>

이제 브라우져를 통해 작성한 코드를 확인해보자. 얼핏보기엔 기능이 매우 훌륭하게 동작하는 듯이 보이지만 사실 이 코드는 잠재적인 문제가 상당히 많은 코드이다. 왕년에 스타크래프트로 날렸던 기억을 떠올리며 'div.btn' 요소에 마우스를 넣다 뺐다 빠르게 반복해보자.

힘껏 마우스를 왔다갔다 하고 멈추었더니 이젠 'mouseenter', 'mouseleave' 이벤트가 마우스를 움직이지 않음에도 마우스의 반복횟수만큼 자동으로 실행되고 있다. 이것은 코드 상의 문제는 아니지만 사용자 경험에 의하면 엄연히 오류로 취급될 수 있으며 개발자가 수정해야할 버그인 셈이다.

해결법은 jQuery의 is()함수를 이용해 해당 요소가 애니메이션일 경우에 중복해서 또 다시 이벤트를 발생시키지 않도록 하는 방법이 있다.

<script>
$('.btn').bind({
mouseenter: function() {
var $btn=$('.hideMenu');
if(!$btn.is(':animated')) $btn.slideDown();
},
mouseleave: function() {
$('.hideMenu').slideUp();
}
});
</script>

위와 같이 is()함수를 이용해 애니메이션이 아닌 상태에만 애니메이션을 적용하도록 한다면 불필요한 애니메이션 효과를 줄일 수 있다. 다만 mouseleave 이벤트에서는 반드시 해당 요소가 사라져야 한다는 전제조건이 따르므로 상태에 상관없이 무조건 해당 요소가 사라지게 해야 함은 주의해야할 부분이다.

덧글

  • 오뎅과국물 2013/10/29 22:53 # 삭제 답글

    셀렉터 하나로 해결되다니 역시 jQuery는 굉장하네요.
    lock 변수를 만들어서 뻘짓하다가 실패해서 헤매다가
    덕분에 잘 해결하고 갑니다. 감사합니다.
  • 승승이 2014/01/22 16:51 # 삭제 답글

    저거 되게 거슬렸는데 이렇게 쉽게 해결할수있다니..
    감사합니다.
  • 여우별 2014/04/05 23:52 # 삭제 답글

    아니 이렇게 간단할수가.... 정말 감사합니다 ^^
    몇달간 못잡은 버그 단번에 잡았네요.. ㅎ
  • 오~ 2017/08/03 17:14 # 삭제 답글

    외국 구글링 해결법 통틀어서 겨우 이거 하나 찾았네요
    감사합니다!
  • ㅇㅇ 2018/08/27 15:47 # 삭제 답글

    저기에 바인드로 감싸는 이유가 뭔지 알 수 있을까요? 그냥 mouseenter랑 mouseleave를 묶지 않고 따로따로 두면 is 셀렉터가 안먹히나요?
댓글 입력 영역