본문으로 바로가기

Modernizr.mq 활용편

category Code Lab 2016. 9. 29. 13:16

모더나이저와 미디어쿼리 활용

앞선 글에서 모더나이저와 디텍타이저를 둘러봤다면 한 번쯤 사용해야겠다라고 생각할 것입니다.

특히, 현재 국내 트렌드상 RWD(반응형웹)를 구축해야하는 경우라면 커다란 이점을 가져다 줄 것입니다.

이 글에서는 모더나이저를 사용하면서 국내 환경의 RWD에 대처하는 방법을 강구해봅니다




미디어쿼리를 사용하기에 앞서

일반적으로 국내에서는 RWD의 환경에 적합하지 않는 것 같습니다. 

물론 소규모 사이트의 경우는 적합하지만 콘텐츠가 많은 사이트의 경우는 절대 적합하지 않음에도 클라이언트는 그 요구를 관철시키려 하고 우리는 이를 수용해야만 합니다.

또한 RWD는 단어 의미론적으로도 알 수 있듯이 디자인에 반응하는 것이며 좀 더 구체적으로 디바이스에 따라 디자인을 달리하는 테크닉이라고 할 수 있습니다.

하지만 클라이언트는 여기서 요구를 멈추지 않고 데스크톱의 윈도우를 리사이징(resizing)을 했을 경우에도 디자인이 반응하기를 요구합니다.

혹여 "윈도우 리사이징을 했을 경우에 디자인이 변해야 하는거 당연한거 아니야?" 라고 질문한다면 다르게 생각해 필요가 있습니다.

예를 들어, 지금 하려는 모더나이저는 물론이고 현존하는 라이브러리 중에는 리사이징을 했을 때 디바이스를 체크하진 않습니다.

다만, 미디어쿼리가 미디어 사이즈에 반응하기 때문에 윈도우에서 리사이징을 했을 때 반응을 보이는 것 뿐인데 이를 두고 RWD(Reponsive Web Design)라고 한다면 잘못 이해하고 있는 것입니다.

만약 그렇게 이해한다면 RWD는 Resize Web Design 이 되어야 할 것입니다.


하지만 이렇게 클라이언트가 설득된다면 다행스럽지만 그렇지 않다면?

미디워쿼리로 막노동을 해야하는 수고가 들 것이고 수많은 디바이스에 따라 breaking point 가 복잡해 질지도 모릅니다.

이러한 여러가지 이유 때문에 모더나이저와 디텍타이저의 도움을 받는다면 클라이언트의 요구사항은 물론이고 훨씬 수월한 프로젝트 환경을 구축할 수 있을 것입니다.



Modernizr.mq()

모더나이저의 사용 방법은 앞선 내용을 참고하시기 바랍니다.

모더나이저의 옵션값 중에  Modernizr.mq() 를 항목을 체크하여 모더나이저를 다운로드 받아 스크립트를 포함하도록 합니다.

그리고 detectizr(디텍타이저)는 사용자 환경에 따라 필요충분조건입니다.


html
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
    <meta charset="UTF-8">
    <title>Modernizr.mq()</title>
    <link rel="stylesheet" href="css/style.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="modernizr.js"></script>
</head>

위와 같이 mq 항목을 체크한 모더나이저를 인클루드시킵니다.


Modernizr.mq() 는 CSS 미디어쿼리 문법과 동일한 방식으로 사용가능하고 똑같이 미디어쿼리를 체크(감지)할 수 있습니다.

JavaScript
if (Modernizr.mq('only screen and (min-width: 960px)')) {
    $('body').addClass('desktop');
}


위와 같은 문법을 사용하여 프로젝트 환경에 따른 breaking point를 정하고 웹 페이지의 body 요소에 클래스를 추가할 수 있도록 구성합니다.

여기서 주의할 점은 resizing 이 될 때마다 미디어쿼리를 체크하게 되기 때문에 성능이슈 문제점이 나타납니다.

이에 대한 해결책으로 스로틀링 기법을 사용하도록 하겠습니다.

throttling(스로틀링)은 성능 저하, 예를 들어 윈도우 스크롤 시에 눈으로 확인할 수 없는 많은 양의 "스크롤 이벤트"가 발생할 것이며, 그때마다 뭔가 비교해야 하는 작업이 이루어 질 것입니다. 그리고 여기서는 많은 양의 resize 이벤트가 발생할 것입니다.

즉, 이러한 성능 저하를 방지하려면 이벤트가 발생할 때마다 이벤트 핸들러를 그대로 실행하는 것이 아니라, 어느 정도까지 실행 빈도가 제한되도록 만들면 효과적입니다.

이러한 이벤트 핸들러의 실행 횟수를 제한하는 처리를 "스로틀링"이라고 합니다.


아래 예제는 스로틀링을 실현하는데 jQuery.throttle-debounce 라는 플러그인을 사용합니다.

예를 들어 아래와 같이 지정(1000/15)하면, 스크롤 이벤트가 자주 발생해도 이벤트 핸들러는 1초에 15회이상 실행되지 않습니다.

JavaScript
$(window).on('scroll', $.throttle(1000 / 15, function () {
    // 생략
}));


[깨알 팁] Debounce

소프트웨어적으로 바운스 현상을 제거하는 것을 디바운스라고 합니다

바운스 현상이란 채터링(chattering)이라고도 하는데, 스위치를 on/off 시킬 때 한 번만 on/off 할 경우에도 기계적인 전동이나 접촉에 의해 스위치가 읽어들이게 되면 스위치를 여러번 누른 것으로 잘못 인식될 수가 있습니다.

이러한 현상을 바운스 현상이라고 하며, 이러한 바운스 현상을 제거하는 것을 디바운스(Debounce)라고 합니다.

예를 들어, 탁상용 스탠드의 터치식 버튼을 한번 눌렀다 떼면 등이 켜지고 다시 한번 눌렀다 떼면 등이 꺼집니다. 터치버튼은 마지막으로 on 또는 off 되는 시각을 기억했다가 다음의 on 또는 off 신호가 감지될 때까지의 걸린 시간을 재서, 일정한 시간지연 후에도 여전히 동일한 신호체계를 가지고 있다면 터치버튼은 확실히 on 또는 off 된 것으로 간주하게 됩니다.

자바스크립트로 접근한다면 키보드의 키판을 누를 때의 keyup 이벤트 핸들러를 생각해 보세요.



먼저, 스로틀링 라이브러리를 head에 포함하도록 합니다.

html
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
    <meta charset="UTF-8">
    <title>Modernizr.mq()</title>
    <link rel="stylesheet" href="css/style.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="modernizr.js"></script>
    <script src="jquery.throttle-debounce.min.js"></script>
</head>


성능 최적화를 고려한 위의 스로틀링을 이용하여 body 요소에 desktop, tablet, mobile 클래스명을 추가할 수 있도록 다음과 같이 구성합니다.

JavaScript
var $body = $('body'),
    isClass = null;
function mqDetect() {
    if(isClass != null) {
        $body.removeClass(isClass);
    }
    if (Modernizr.mq('only screen and (min-width: 960px)')) {
        $body.addClass('desktop');
    } else if (Modernizr.mq('only screen and (min-width: 600px)')) {
        $body.addClass('tablet');
    } else  {
        $body.addClass('mobile');
    }

    isClass = $body.attr('class');
};
mqDetect();

$(window).on('resize', $.throttle(1000 / 15, function(){
    mqDetect();
}));


위의 코드를 가지고 사용자 페이지에서 윈도우창을 리사이징하면서 body 의 클래스명을 확인해 보시기 바랍니다.



Jaehee's WebClub



댓글을 달아 주세요