본문 바로가기
프로그래밍/HTML, CSS

반응형 웹에서의 자바스크립트를 반응형으로 사용하기

by pentode 2018. 4. 9.

반응형 웹을 만들기 위해서 CSS3 미디어 쿼리를 이용하여 화면 크기에 따라 적용하는 스타일을 달리하는 방법은 "반응형 웹을 위한 미디어 쿼리 사용법(CSS media queries)에서 알아 보았었습니다.

 

화면 크기에 따라 스타일 시트를 변경하여 페이지내의 요소들의 사이즈를 늘리고 줄이거나, 위치를 변경하고, 보이거나 감추거나 하는 작업을 할 수 있습니다. 원하는 디자인이 이러한 것들 뿐만 아니라 제목의 길이를 줄이거나, 이미지를 교체하거나, 특정 요소를 클릭했을 때의 동작을 변경하거나 하는것이 필요하다면 CSS만으로는 구현하기가 힘듭니다.

 

PC에서 보여줄 것과 휴대기기에서 보여줄것을 따로 만들고, 각각에 필요한 이벤트를 자바스크립트로 구현한 후 화면 크기에 따라 숨기거나 보여주는 CSS를 이용해서 처리할 수도 있습니다. 하지만 이 방법은 같은 컨텐츠 를 중복해서 두 세트 다운로드 해야 하므로 시간과 데이터가 많이 소모될 수 있습니다. 될 수 있으면 하나의 컨텐츠를 잘 조작해서 다르게 보여주는게 좋을 것입니다.

 

window.mediaMatch() 함수는 미디어 쿼리에서 사용되는 것과 동일한 표현식을 사용하여 조건에 따라 다른 스크립트를 실행할 수 있습니다.

 

먼저 mql.matches 프로퍼티를 이용하여 표현식이 참인지 확인할 수 있습니다.

 

var mql = window.matchMedia("screen and (max-width: 768px)");

if (mql.matches) {
	console.log("화면의 너비가 768px 보다 작습니다.");
} else {
	console.log("화면의 너비가 768px 보다 큽니다.");
}

 

리스너를 붙여서 사이즈가 변할 때의 이벤트 발생을 감지할 수 있습니다.

 

var mql = window.matchMedia("screen and (max-width: 768px)");

mql.addListener(function(e) {
	if(e.matches) {
		console.log('모바일 화면 입니다.');
	} else {
		console.log('데스크탑 화면 입니다.');
	}
});

 

window.matchMedia() 함수는 CSS3 미디어 쿼리 처럼 거의 모든 최신 브라우저에서 지원합니다. 인터넷 익스플로러는 10 버전 부터 사용할 수 있습니다. media query 가 IE 9 부터 사용할 수 있는것과 비교하면 차이가 있습니다. IE 9 이하에서 mediaMatch를 사용하려면 polyfill 을 사용해야 합니다.

 

오래된 브라우저를 지원해야 한다면 자바스크립트 API, 지원 되는 CSS, 그 외에도 많은 third party 자바스크립트 라이브러리들의 버전들이 모두 호환 되도록 매칭 시키는 것은 상당히 까다로운 작업이 됩니다.

 

많이 사용되는 jQuery는 IE 9 이상을 사용한다면 3.x 대 버전을 사용하는 것이 좋습니다. IE 6 ~ 8까지 지원해야 한다면 1.x 대 버전을 사용해야 합니다.

 

mediaMatch() 를 IE 9 에서 동작하도록 해주는 polyfill 입니다.

 

https://github.com/paulirish/matchMedia.js/

 

다음과 같이 사용합니다.

 

<!--[if IE 9]>
<script type="text/javascript" src="./matchMedia.js"></script>
<script type="text/javascript" src="./matchMedia.addListener.js"></script>
<![endif]-->

 

IE 8 이하라면 좀 복잡해 집니다. 이 구간에서는 CSS3 미디어 쿼리도 동작을하지 않고, matchMedia()도 동작을 하지 않습니다. 두 가지 모두 polyfill을 사용해야 합니다. 이를 위해서 respond.js 와 Media.match 등 몇가지를 조합해 봤는데, 개개의 성능이 좋은 것들은 충돌이 있어서 동작을 하지 않았습니다. 성능은 그리 좋지 못하지만 동작은 하는 조합이 아래의 Media.match 와 css3-mediaqueries.js 의 조합인 것 같습니다.

 

 

IE 9 ~ 6 polyfill인 Media.match 입니다.

 

https://github.com/weblinc/media-match

 

다음과 같이 사용하였습니다. css3-mediaqueries.js 는 미디어 쿼리가 IE 8 이하에서 동작하도록 해주는 polyfill 입니다.

 

<!--[if lte IE 8]>
<script type="text/javascript" src="./media.match.min.js"></script>
<script type="text/javascript" src="./css3-mediaqueries.js"></script>
<![endif]-->

 

테스트 이미지 입니다.

 

 

matchMedia()를 사용하지 않고 동일한 작업을 할 수 있는 다른 대안이 있습니다. 브라우저의 resize 이벤트를 직접 처리해서 동일한 기능을 제공하는 라이브러리로 SimpleStateManager 가 있습니다. 브라우저의 다양한 상태에 이벤트를 처리할 수 있는 기능을 가지고 있습니다. 그런데 3.x 버전은 내부적으로 mediaMatch() 를 사용하고 있어서 IE 9 이하에서는 polyfill이 필요합니다. 2.x 버전에서는 mediaMatch() 를 사용하지 않으므로 모든 버전에서 사용할 수 있습니다.

 

https://github.com/SimpleStateManager/SimpleStateManager

https://github.com/SimpleStateManager/SimpleStateManager/tree/2.5.0

 

 

※ 참고 라이브러리

 

matchMedia()와 미디어 쿼리를 편리하게 사용할 수 있도록 도와주는 라이브러리 입니다.(IE 9 이하에서는 polyfill이 필요합니다.)

 

http://wicky.nillia.ms/enquire.js/

 

IE 6~8 버전에서 미디어쿼리를 해석할 수 있도록 만들어주는 자바스크립트 라이브러리입니다.

 

https://github.com/scottjehl/Respond/

 

※ 테스트에 사용된 소스

responsive.zip
다운로드

 

 

반응형