업데이트:

요즘은 포스팅을 각 주제별로 하지 않고, 일정 주기마다 주제들을 모아서 하나의 포스트를 작성하는 방식에 익숙해지려고 함.. 포스트가 점점 늘어날수록 찾기 힘든 게 결정적인 이유인데, 찾기 편하려고 태그/카테고리별 분류, 검색 기능을 넣어놓긴 했으나 후자의 방식이 개인적으로 재밌어진 것도 있다. 아무튼, 최근 실무/학습에서의 삽질과 그로 얻은 귀중한(?) 깨달음을 간추려보았음.

다 써놓고보니 JS 밖에 없.. 의도한 건 아님..

$(window).on(“load”)를 $(document).ready 안에 작성해선 안된다.

1
2
3
4
5
6
7
8
9
$(function() {
    console.log("1");

    $(window).on("load", function() {
        console.log("2");
    });
});

// 결과 : 1

결론부터 말하면 저렇게 작성할 경우 작동하지 않는다. 저렇게 썼다가 의도한대로 안 나와서 찾아보니 jQuery 버전 3 이상부터 $(document).ready는 비동기 방식으로 동작하며, $(window).on("load")$(document).ready 안에 포함시킬 수 없다고 함.

1
2
3
4
5
6
7
8
9
$(function() {
    console.log("1");
});

$(window).on("load", function() {
    console.log("2");
});

// $(document).ready가 비동기 방식으로 작동하므로 코드의 실행 순서는 2 → 1이다.

때문에 $(window).on("load")를 외부로 빼면 정상적으로 작동한다. load말고 resize 등 $(window)에 이벤트를 바인딩할 땐 무조건 $(document).ready 밖으로 빼는 게 좋을 듯.

참고 링크


jQuery 이벤트가 실행되지 않게 하기

vanilla JS로는 removeEventListener 함수로 이벤트 리스너를 삭제하면 되는데, jQuery로 어떻게 하더라.. 떠오르지 않았다. 구글링도 이상하게 했는지 답은 찾을 수 없었고, 결국 해결하긴 했음. 일단 문제의 코드는 다음과 같다.

1
2
3
$(".element").on("mouseover focusin", function() {
    ...
});

반응형 브라우저에서 테스트해보니 mouseover와 focusin 이벤트가 겹쳐서 오류가 났었다. 그래서 애꿎은 마크업, CSS에 문제가 있나 찾아보고, 결국 mouseover를 특정 분기점에서 실행 안되게 하려고 삽질 끝에 아래와 같이 작성하였다.

1
2
3
4
5
6
7
$(".element").on("mouseover focusin", function(event) {
    if ($(window).outerWidth() <= 1200 && event.type === "mouseover") {
      return;
    }

    ...
});

반응형(1200px 이하)일 때 & event.type이 mouseover일 때는 함수가 실행되지 않게 만들었다. 더 좋은 방법이 있음을 알지 못한 채..

1
2
3
4
5
6
7
$(".element").on("mouseover focusin", function() {
    ...
});

if ($(window).outerWidth() <= 1200) {
    $(".element").off("mouseover");
}

그냥 jQuery에서 제공하는 off 함수로 이벤트를 삭제해주면 된다.

모바일에서 이벤트가 겹치지 않게 하기

1
2
3
4
5
6
7
8
9
10
$(".element").on("click", handlerClick);
$(".element").on("touchstart", handlerTouchstart);

function handlerClick() {
    ...
}

function handlerTouchstart() {
    ...
}

위 코드에서 PC에선 click이, 모바일에선 touchstart로 핸들링되어야 하는 로직을 어떻게 구성해볼 수 있을까? 위에서 제시한 window의 너비값을 비교하는 방법이나 event의 type을 검사하는 것보다 더 효율적인 방법이 있는데,

1
2
3
4
5
6
7
8
9
10
11
var returnEvent = (function() {
    if ("ontouchstart" in document.documentElement === true) {
        return "touchstart";
    } else {
        return "click";
    }
})();

$(".element").on(returnEvent, function() {
    ...
});

click 이벤트가 있는지 검사해서 있으면 click을, 없으면 대체할 이벤트를 반환하는 함수를 만들어서 쓰면 된다. 최근 블로그 JS 작업 중 알게 된 방법인데, 실무에 써먹기에 유용할 듯싶음.