2016년 1월 8일 금요일

jQuery animate() 메소드의 중첩(중복) 실행 방지하기

인터넷 익스플로러(이하 IE)가 웹 브라우저 시장을 독점하던 시절, 파이어폭스, 오페라, 크롬 등 비주류였던 웹 브라우저들은 꾸준한 업데이트를 통해 빠르게 웹 표준을 받아들였지만, IE 시리즈는 2011년 출시 된 9부터 비로소 HTML5 표준 권고안을 일부 채용하면서 새로운 웹 표준에 한 발짝 다가섰다. 공정히 말하면 표준을 받아들인 시기는 크게 달랐다고 할 수 없지만 브라우저 자체를 업데이트하지 않고 레거시 엔진을 별도 탑재한 새로운 버전을 발표했다는 점이 IE의 가장 큰 문제였다.

IE가 왜 그렇게 큰 난관으로 불리우는지 모르는 사람들을 위해 한국의 기형적인 웹 생태계 문제부터 시작해서 밤을 새우며 이야기를 하고 싶지만 생략한다. Trident의 레거시 코드를 대거 삭제하고 표준 웹 브라우저를 표방한 Edge에서도 여전히 다양한 문제가 발생하고 있는 마당에 IE8 이하의 호환성에 대해서는 논할 필요도 없을 것이다.

IE의 시장 점유율을 무시할 수 없었던 2010년대 초중반의 웹 사이트 개발 프로젝트에서는 레거시 브라우저에 대한 지원이 당연한 이슈로 받아들여졌고, 웹 디자이너와 퍼블리셔에게 polyfill이나 shim(혹은 shiv)은 아주 친근한 단어였다. 하지만 근래에는 웹 브라우저가 다양해지고 모바일 기기를 통한 인터넷 접속 비율이 높아지면서 IE8 이하의 웹 브라우저를 위한 fallback을 기획 단계부터 배제하고 프로젝트를 진행하는 경우가 많다.

불과 3, 4년 전의 상황에 비하면 장족의 발전이라고 할 수 있지만 문제는 현재 크로스브라우징의 마지노선으로 여겨지는 IE9도 완벽하게 HTML5와 CSS3를 지원하지는 않는다는 점이다.

코드 불러오는 중...

CSS3의 transition 속성은 개체에 부드러운 전환 효과를 적용하기 위해 자주 사용된다. 위 코드펜의 단어에 마우스를 hover하면 IE10 이상의 브라우저(크롬 26.0+, 파이어폭스 16.0+, 사파리 6.1+, 오페라 12.1+)에서만 정상적으로 transition 효과가 출력된다. 모바일 브라우저에서는 hover 효과가 실행되지 않고 브라우저에 따라 클릭시 호버 상태로 고정된다.

이러한 이유로 transition 속성을 대체하기 위한 크로스브라우징 기술로 흔히 사용되는 것이 jQuery의 animate() 메소드이다.

코드 불러오는 중...

위 코드는 일견 문제가 없는 것처럼 보이지만 마우스를 여러 번 빠르게 hover하여 mouseenter와 mouseout을 반복해 보면 animation() 메소드가 중첩 실행된다는 것을 알 수 있다. 이는 위와 같은 단순한 코드 뿐만 아니라 모든 형태의 animate 효과에서 나타나는 문제이다. 이러한 현상을 방지할 수 있는 가장 쉬운 방법은 stop() 메소드를 이용하는 것이다.

코드 불러오는 중...

stop()은 호출과 동시에 현재 해당 객체에 실행되고 있는 animation을 정지시키기 때문에 animation() 메소드에 체이닝을 시켜두면 간단히 중첩 실행을 방지할 수 있다. 편리하고 직관적인 해법이지만 아래와 같은 경우에는 오히려 stop() 메소드가 독이 된다.

코드 불러오는 중...

위 코드에서는 개체가 정해진 거리를 부여된 duration 매개변수에 따라 이동하는 동안 stop() 메소드가 animation을 중단시키고 새로운 animation이 시작되기 때문에 이동 구간이 중첩되는 문제가 발생한다. duration 단위 이상의 rate로 animation을 갱신하면 정상적으로 동작하지만 duration 값보다 빠르게 갱신을 시도하면 animation 시퀀스가 깨지게 된다. 이 경우 stop() 체이닝을 대체할 수 있는 수단은 아래와 같다.

코드 불러오는 중...

위 코드에서는 절대값을 구하는 Math.abs 함수와 현재 시간을 출력하는 $.now를 이용, timer 변수에 animation 시작 시간을 기록하고 이전 animation 시작 시간과의 차이가 duration 값 이상일 경우에만 animation을 실행하도록 입력 이벤트를 제어한다. 모바일 브라우저에서 코드펜 렌더링 오류가 발생하는 경우가 있으나 실적용시에는 정상 작동한다. 이 방법은 슬라이더를 제작할 때 유용하게 사용할 수 있다.

댓글 없음:

댓글 쓰기