씽크패드 펑션키 밖으로 뺀 사람 찾아서 조사버리겠다… 아무튼… 포고 인벤토리 보고 생각났던건데 이제서야 함… 귀차니즘이 이렇게 무섭습니다 여러분.
https://github.com/koreanraichu/Javascript/tree/92e1d14bc15406e191c09a6cb88edc25393f0f3d/List-grid
코드는 여기 가서 봅시다. HTML이나 CSS 관련 코멘터리는 안할거임.
발단
일단 발단이 뭐냐…
위가 리스트 뷰, 아래가 그리드 뷰이다. 포켓몬고의 인벤토리는 원래 위쪽만 있었다가, 아래쪽도 일부 계정에 시범적용 후 현재는 전 계정에서 해당 설정을 할 수 있게 되었다.
일단 두 방식은 각각 장/단점이 있는데
리스트 뷰는 위의 사진처럼 아이템의 설명을 확인할 수 있고, 버리기 아이콘도 줄의 끝에 있기 떄문에 아이템이랑 거리가 있어서 아이템의 조작이 상대적으로 편하다. 하지만 도구가 많아질수록 표시하는 데 필요한 페이지 길이가 길어지기때문에 스크롤하기가 매우 귀찮고, 카테고리에 따라서는 가지고 있는 아이템의 종류와 수량을 한번에 파악하기가 어렵다는 단점이 있다. 위쪽은 도구이고 평소에는 일부 도구를 정리해서 저 정도지만, 저기에 상처약 두 종류만 추가돼도 리스트 뷰에서는 한번에 못 본다. 루어 모듈도 마찬가지.
그리드 뷰는 장단점이 리스트 뷰와 반대이다. 일단 한 눈에 아이템의 개수와 종류가 확 들어오고, 상대적으로 리스트 뷰에 비해 필요한 페이지 길이도 짧아서 스크롤 노가다를 덜 해도 된다. 하지만 아이템과 삭제버튼 간 간격이 좁기때문에 아이템을 버리려다가 다른 아이템을 선택하게 되는 사태가 자주 일어난다. 그리고 나야 본가 게임을 꽤 해봤지만 아예 포고로 처음 포켓몬을 접하거나, 아이템이 처음 보는 거라 설명이 필요할 때가 있는데, 이 때 그리드 뷰는 설명이 안보이기때문에 불편할 수도 있다.
만들어보자
일단 네이버 글자 제한때문에 HTML 코드는 여기 다 못 올린다. 그러니 같이 보고 싶으면 깃헙으로 갑시다. 위에 주소 써뒀음.
<div class="button"> <!-- 전환 버튼이 위치할 곳 -->
<label class="switch">
<input type="checkbox">
<span class="slider"></span>
</label>
</div>
위에 이 부분은 슬라이드 버튼이다. w3school에서 긁어온건데 이번에는 네모네모 버튼으로 긁어봤음. 그리고 아래쪽이 본체다.
버튼과 아이템을 wrap이 싸고 있고, 버튼 밑에 아이템이 본체인데
대충 이런 구조… 길어서 아이템족은 또 접었는데 item-wrap 안에는 아이콘과 컨텐츠가 들어있다.
그래서 이런 식으로 리스트 뷰가 적용되는거다. CSS는 후가공 몇번 했음… ㅡㅡ 옆에 있는거 독이니까 당황하지 마십쇼. 지금 이 글 쓰는 OS 리눅스임.
여기서 그리드 뷰로 바꾸는 방법은 간단하다. 첫번째, 그리드 뷰로 바꿀 때 바뀔 요소에 대해 CSS를 적용한다(grid 클래스를 주고). 두번째, JS로 토글되게 한다. 그러면 JS보다 골치 덜 아픈(안아프다고 안했음) CSS부터 들어가보자… 예전에 다크모드 포스팅 한 걸 보셨던 분들이라면 아시겠지만, 그거 비슷하게 돌아간다.
.item.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 5px;
align-items: center;
justify-content: center;
}
.icon.grid {
max-width: 100%;
margin: 0 auto;
font-size: 5em;
height: auto;
width: auto;
}
.contents.grid {
display: none;
}
일단 여기서 그리드 뷰로 바꾸게 되면 바뀌는 거 세 가지다. 아이템(아이템 래퍼를 담고 있는 거)은 display가 그리드가 되고, 3등분 그리드로 안의 컨텐츠를 담는다. contents는 대충 설명같은 느낌인데(위에 보면 아이콘 옆에 있는 글이 contents), 그리드 뷰에서는 contents를 안 보이게 할거니까 display 속성을 none으로 했다. 그리고 아이콘의 경우 크기를 더 키웠다. 아니 쟤가 제일 잘 나가니까 당연한거 아님?
//가져올건 이 쪽
let toggleButton = document.querySelector('.slider');
let viewItem = document.querySelector('.item');
let viewCont = document.querySelectorAll('.contents');
let viewIcon = document.querySelectorAll('.icon');
//실행 코드
toggleButton.addEventListener("click", function () {
if (viewItem.classList.contains('grid')) { //.item은 하나밖에 없어서 하나만 가져왔습니다
viewItem.classList.remove('grid');
} else {
viewItem.classList.add('grid');
}
viewCont.forEach(function (item) {
if (item.classList.contains('grid')) { //컨텐츠와 아이콘은 HTML파일에 추가된 숫자만큼 여러개 있어서 forEach로 해결
item.classList.remove('grid');
} else {
item.classList.add('grid');
}
})
viewIcon.forEach(function(item){
if(item.classList.contains('grid')) {
item.classList.remove('grid');
} else {
item.classList.add('grid');
}
})
}, false);
그러면 자바스크립트에서 이거 바꿀 수 있게 해야 한다고 했는데… 그러면 동작 지시할 버튼과 바꿀 요소를 가져와야 한다. 위에 있는 건 버튼이고, 아래 세 줄이 바꿀 요소들. forEach가 들어간것과 안 들어간 것의 차이? HTML에 뭉텅이로 있으면 forEach로 순회하면서 작업해야 다 바뀜….
나도 포고해야되니까 최대한 간결하면서도 이해하기 쉽게 설명해봅시다. item 클래스를 가지고 있는 건 HTML 파일에 하나밖에 없고, grid 클래스가 붙으면 3열짜리 그리드로 바꿀 거다. 반면 아이콘이나 콘텐츠도 별도의 클래스를 부여하고 그리드 븅 맞게 바꾸는 건 맞지만 얘네는 HTML 안에 여러개가 있다. 다행히도(?) 동적 생성은 아니고 수제로 복붙함…
아무튼 그런 과정을 거쳐서 이런 식으로 토글할 수 있다. 저거 근데 다크모드때처럼 버튼 통으로 가져왔다니 이벤트 두번 적용되더라… ㅡㅡ
Reply