이번에 반응형으로 slick(carousel)을 구현하며 겪은 문제가 있다.
브라우저의 크기가 변경되면 slick이 한 화면에 보여주는 슬라이드의 수가 유동적으로 변하게 된다. slick은 마지막 페이지에 도달하면 다음 페이지로 이동하지 못하게 막아야하므로
다음 처럼 총 6개의 슬라이드가 있다고 가정한다면
2개의 슬라이드씩 넘어갈 때는 3번을 넘길 수 있지만, 3개의 슬라이드가 넘어갈 때는 2번만 넘어가도록 만들어야 했다. 즉 slick의 총 페이지가 3에서 2로 줄어드는 것! 본인은 css의 media qeury를 통해 화면의 크기에 따라 한 화면에 보여지는 슬라이드 수를 조절 했는데, css에서는 페이지의 수를 결정할 수 없었다. 그래서 이 포스트에서는 js에서 화면의 크기를 취득해 유동적으로 slick의 총 페이지 수를 계산하여 view를 조작하는 방법에 대해 소개한다.
예시
2 slides on one page
3 slides on one page
그래서 찾아본 방법중 screen.window.availWidth가 있었다. mdn에서는 "The Screen.availWidth property returns the amount of horizontal space (in pixels) available to the window."(window 창에서 이용가능한 너비 공간을 반환한다.) 라는 글을 읽고 브라우저 창의 크기에 따라 값이 변동될 것이라고 생각했다. 하지만 실제로는 아니었다.
왜 이 같은 문제가 발생하는지 찾아보았고 그 해답은 web api의 특성에 있었다. 아래에 그 내용을 소개한다.
window.screen.width는 모니터의 해상도이다. 따라서 노트북, 모바일 등 해상도가 다른 디바이스마다 값이 다르다.
하지만 같은 디바이스에서는 죽었다 깨어나도 값이 바뀔일이 없다.
본인이 햇갈렸던 api다. api 이름으로만 보면 브라우저의 크기에 따라 그 값이 변동되는 것처럼 느껴지지만 실상은 그렇지 않다.
window.screen.width와 성질은 같다. 역시나 모니터 해상도에 따라 값이 정해지며, 다만 상단의 툴바와 같은 영역을 제외하고 screen size가 결정된다. 주의할 점은 브라우저의 크기를 줄여도 무조건 모니터의 해상도가 기준이 되어 툴바 영역을 배제한다는 점이다.
console.log(
'availHeight: ',
window.screen.availHeight,
'height: ',
window.screen.height
); // availHeight: 1050 height: 1080
innerWidth는 브라우저 윈도우 창틀(외부 영역)을 제외한 크기를 표시한다. 반대로 window.outerWidth는 창틀까지 포함한 영역을 의미한다.
디바이스의 크기가 아니라 브라우저의 창의 크기에 따라 slide의 개수가 정해지기 때문에, window.innerWidth를 사용해야 한다.
React에서 커스텀 훅에 window.innerWidth를 사용해 봤다.
resize 이벤트는 window의 크기가 변할 때 트리거 된다. resize 이벤트와 window.innerWidth를 함께 사용하여 문제를 해결했다.
import { useEffect, useState } from 'react';
export default function useWindowWidth() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
window.addEventListener('resize', () => {
setWindowWidth(window.innerWidth);
});
}, [windowWidth]);
return windowWidth;
}