💻 수원특례시청 클론 코딩
사이트명: 수원특례시청
제작기간: 24.03.16 ~ 24.03.20(4일 소요)
사용언어: html, css, js
분류: 반응형
수원시청은 웹 접근성을 고려하여 작업한 사이트이다. 따라서 키보드 만으로도 제공되는 모든 컨텐츠에 접근할 수 있게 만들고자 했다.
GNB 메뉴에 마우스를 올리면 LNB 영역이 보여지는데 이 부분을 키보드 TAB 키로 접근 시에도 바로 열릴 수 있도록 하고, 첫 번째 메뉴에서 shift + tab 키를 누르거나 마지막 메뉴에서 tab 키를 누르면 네비게이션이 닫힐 수 있도록 처리했다.
사용한 이벤트 & 속성
키보드 이벤트 - keydown
KeyboardEvent는 사용자가 키를 누르거나 키를 놓을 때 발생한다. 키를 누를 때는 keydown 타입의 이벤트가 발생하고, 키를 놓을 때는 keyup 타입의 이벤트가 발생한다.
포커스 이벤트 - focus
대상 요소로 포커스가 이동하면 이벤트를 발생한다.
shiftKey 속성
이벤트가 발생했을 때 shift키가 눌렸는지(true), 눌리지 않았는지(false) 나타내는 불리언(boolean) 값
Key 속성 - 'Tab'
e.key === 'Tab' 로 키보드 tab 키가 눌렸는지 여부를 확인하였으며 e.code === 'Tab' 혹은 e.keyCode === 9(Deprecated)로도 대체할 수 있다.
관련 설명
focus 이벤트를 추가하여 키보드 tab 키를 눌렀을 때 네비게이션이 열리도록 하였다.
$('.link-gnb').on('mouseenter focus', function () {
navIndex = $(this).parent().index();
openNav(navIndex);
})
// 첫 번째 lnb
$('.lnb-item:first-child .link-lnb').on('keydown', function (e) {
navIndex = $(this).parents('.gnb-item').index();
if (e.key === 'Tab' && e.shiftKey) { // shift + tab 키를 눌렀다면 조건 발생
if (navIndex === 0) { // lnb를 담고있는 gnb가 첫 번째 요소라면
closeNav(); // 네비게이션 닫기
} else {
openNav(navIndex - 1); // 이전 네비게이션 열기
}
}
});
첫 번째 lnb에 포커스 된 상태에서 shift + tab 키를 누를 경우
부모 gnb가 첫 번째에 위치한다면 네비게이션이 닫히고,
그렇지 않다면 이전 네비게이션이 열린다.(예를 들어 현재 3번에 위치할 경우 2번 네비게이션이 열림)
// 마지막 lnb
$('.lnb-item:last-child .link-lnb').on('keydown', function (e) {
navIndex = $(this).parents('.gnb-item').index();
const navTotal = $('.gnb-item').length;
if (e.key === 'Tab' && !e.shiftKey) { // tab 키를 눌렀다면 조건 발생
if ((navIndex + 1) === navTotal) { // lnb를 담고있는 gnb가 마지막 요소라면
closeNav(); // 네비게이션 닫기
} else {
openNav(navIndex + 1); // 다음 네비게이션 열기
}
}
});
마지막 lnb에 포커스 된 상태에서 tab 키를 누를 경우
부모 gnb가 마지막에 위치한다면 네비게이션이 닫히고,
그렇지 않다면 다음 네비게이션이 열린다.(예를 들어 현재 3번에 위치할 경우 4번 네비게이션이 열림)
// 첫 번째 gnb
$('.link-gnb:first-child').on('keydown', function (e) {
if (e.key === 'Tab' && e.shiftKey) { // shift + tab 키를 눌렀다면 조건 발생
closeNav(); // 네비게이션 닫기
}
})
키보드 tab 키로 이전 혹은 다음 네비게이션을 열 때 먼저 gnb에 포커스가 된다. 그래서 lnb에 사용한 코드 만으로는 shift+ tab 키로 영역을 아예 빠져나갈 때 네비게이션이 닫히도록 할 수 없다.
따라서 위 코드를 추가하여 shift + tab 키로 영역을 빠져 나갈 경우에도 네비게이션이 닫힐 수 있도록 하였다.
📂 완성코드
나는 fraction 타입이면서 숫자가 두자리 수로 출력되고 구분선은 하이픈(-)으로 만들어야 했다. Swiper에서 제공하는 기본 설정은 한자리 수에 구분선은 슬래시(/) 기호였기에 커스텀을 하였는데 작업한 내용을 정리해보고자 한다.
수정 전(Default)
스와이퍼에서 제공하는 renderFraction 메서드를 사용해서 변경할 수 있다.
이 매개변수를 사용하면 "분수" 페이지 매김 HTML을 사용자 정의할 수 있습니다. 'fraction'페이지 매김 유형 에만 해당 - Swiper API
renderFraction 적용한 코드
new Swiper('.swiper', {
pagination: {
el: '.swiper-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return '<span class="' + currentClass + '"></span>' +
' - ' +
'<span class="' + totalClass + '"></span>';
}
}
});
형식분수현재
분수 페이지 매기기 현재 숫자 형식을 지정합니다. 함수는 현재 숫자를 받고 형식화된 값을 반환해야 합니다.
형식분수합계
형식 분수 페이지 매김 총 수입니다. 함수는 총 개수를 수신하며 형식화된 값을 반환해야 합니다.
- Swiper API
현재 페이지 번호는 formatFractionCurrent 메서드로, 전체 페이지 번호는 formatFractionTotal 메서드로 수정할 수 있다. 여기서 사용된 padStart() 메서드는 String에서 제공하므로 숫자 타입을 문자 타입으로 변환해서 적용하면 완성이다!
📂 완성코드
수원시청 사이트 헤더 영역에 화면을 확대하거나 축소할 수 있는 줌 버튼이 존재한다. 플러스(+) 기호를 누르면 body 요소에 transform scale 값이 0.1씩 증가하며 마이너스(-) 기호를 누르면 반대로 0.1씩 감소한다. 기본 값은 scale(1)이다. 나도 동일한 동작성을 추가하고 싶어서 아래와 같이 코드를 작성해 보았다.
💡 화면 보기
여기서 가장 중요한 것은, transform-origin 속성을 left top으로 적용하는 것이다.
transform-origin의 초기값은 center center라서 화면 가운데를 기준으로 확대/축소 되어 위와 같은 동작성을 만들 수 없다.
개인적으로 수원시청 사이트의 화면 확대 & 축소 방법에 놀랐는데, 이유는 REM 단위를 사용하지 않고 scale 속성으로 처리한 부분이 신박하다고 느꼈다.
참고 사이트
https://swiperjs.com/