"버튼 클릭 시 영화 카드 리스트의 제목을 기준으로 오름차순, 내림차순으로 정렬"되도록 기능을 구현하던 중
- 영화 카드 리스트의 제목 값을 어떻게 따로 추출해야 하는가?
- 홈페이지 내에서 카드가 정렬되는 기능을 어떤 함수와 코드로 작성해야 하는가?
라는 문제에 봉착했다.
다른 팀원분의 코드에서 발전한 팀 프로젝트이기에 사진과 자세한 자료는 첨부가 어려움
-> 최대한 글로 설명해보자면 이렇다.
먼저 제목 값
만 따로 추출하기 위해 다른 팀원분들께 도움을 요청했고,
팀원분들께서 친절하게 설명해주신 덕분에
-> 제목 값을 출력되게 하는 코드를 짜는 것에 성공했다.
// <html>
// dropdown 버튼
// 하위메뉴를 누르면 카드가 정렬되는 방식으로 구현할 예정
<div class="dropdown">
<button class="dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">영화 제목 정렬</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item1" id="dropdown-item1" href="#" onclick="sort1">오름차순</a></li>
<li><a class="dropdown-item2" id="dropdown-item2" href="#" onclick="sort2">내림차순</a></li>
</ul>
</div>
// <script>
// '검사' => 'console'에서 console.log();로 제목 값만 출력되도록
// 팀원분들께서 도와주셨다.
$sort.addEventListener('click', () => {
const $movie_title = document.querySelectorAll('.movie-title');
const sortedTitles = Array.from($movie_title);
sortedTitles.forEach(title => {
console.log(title);
});
});
=>
개발자 도구
->검사
->console
에서 먼저 영화의 제목 값만 출력되게끔 코드를 짰다.
출력결과
=> 이 추출된 제목 값
으로 어떻게
카드를 정렬 시키는 기능을 구현하냐는 것이 다음 문제였다.
->
제목값을 추출한 코드를 기반으로 시도한 코드는 대략 이렇다.
// 시행 착오 _ console.log();
// 오름차순 정렬
$sort1.addEventListener('click', () => {
const $movie_title = document.querySelectorAll('.movie-title');
const sortedTitles = Array.from($movie_title)
.map(item => item.textContent)
.sort((a, b) => a.localeCompare(b));
sortedTitles.forEach(title => {
console.log(title);
card - list;
});
});
// 내림차순 정렬
$sort2.addEventListener('click', () => {
const $movie_title = document.querySelectorAll('.movie-title');
const sortedTitles = Array.from($movie_title)
.map(item => item.textContent)
.sort((a, b) => b.localeCompare(a)); // 내림차순 정렬
sortedTitles.forEach(title => {
console.log(title);
});
});
=> 1번째 시도
&&
// 영화 제목
// 오름차순(2)
$sort1.addEventListener('click', () => {
const $movieContainer = document.querySelector('.movie-container');
const $movieCards = Array.from($movieContainer.querySelectorAll('.movie-card'));
$movieCards.sort((cardA, cardB) => {
const titleA = cardA.querySelector('.movie-title').textContent;
const titleB = cardB.querySelector('.movie-title').textContent;
return titleA.localeCompare(titleB);
});
$movieCards.forEach(card => {
$movieContainer.appendChild(card);
});
});
// 내림차순(2)
$sort2.addEventListener('click', () => {
const $movieContainer = document.querySelector('.movie-container');
const $movieCards = Array.from($movieContainer.querySelectorAll('.movie-card'));
$movieCards.sort((cardA, cardB) => {
const titleA = cardA.querySelector('.movie-title').textContent;
const titleB = cardB.querySelector('.movie-title').textContent;
return titleB.localeCompare(titleA);
});
$movieCards.forEach(card => {
$movieContainer.appendChild(card);
});
});
=> 2번째 시도
현재는 코드가 수정된 시점(버튼을 누르면 출력하는 코드 -> 완성된 코드로 수정됨)에서 쓰는 거라
자세한 출력 결과 사진 첨부가 어렵지만.
대략 제목 값
과 똑같이 console.log();
로
오름차순 (a - b)
숫자(number) > 한글(kr => 가나다) > 영어(en => ABC)
내림차순 (b - a)
영어(en => ABC) > 한글(kr => 가나다) > 숫자(number)
=> 값이 출력되었다.
-> 하지만 어디까지나 console.log();일 뿐,
&&
페이지에서 카드가 정렬되는 기능을 구현하는 것은 막막했다.
= 구글링을 해본 결과
-> 다양한 함수와 다른 개발자들이 공유한 코드의 도움으로 해결할 수 있었다.
$cardList
배열 정렬)=
console.log();
에서만 지속적으로console
에서 값을 출력하는 것이 아닌
forEach
로$cardList
배열을 순회할 수 있다는 사실을 알아냈다.
=
$cardList
를 중점적으로 코드를 짜는 것에만 집중했었는데,
->$cardList
는 그저 카드의 모음일 뿐.카드를 각각 정렬되도록 수행하는 것은 "
$cardList
-$cardList.children
"(부모 - 자식) 관계로 코드를 짜는 것이 더 효율적이었다.
// 실제 실현 코드
const $sort = document.querySelector('#dropdownMenuButton1');
const $sort1 = document.querySelector('#dropdown-item1');
const $sort2 = document.querySelector('#dropdown-item2');
console.log($sort1);
// consol.log(<p class = "movie-title"> "제목")
$sort.addEventListener('click', () => {
const $movie_title = document.querySelectorAll('.movie-title');
const sortedTitles = Array.from($movie_title);
sortedTitles.forEach(title => {
console.log(title);
});
});
// 카드 오름차순 정렬
// html id="dropdown-item" href="#" onclick="sort1" 드롭다운 하위버튼과 연결
$sort1.addEventListener('click', () => {
const $cardList = document.getElementById('card-list');
const $cards = Array.from($cardList.children);
$cards.sort((a, b) => {
const titleA = a.querySelector('.movie-title').textContent;
const titleB = b.querySelector('.movie-title').textContent;
return titleA.localeCompare(titleB);
});
$cards.forEach(card => {
$cardList.appendChild(card);
});
});
// 카드 내림차순 정렬
// html id="dropdown-item2" href="#" onclick="sort2" 드롭다운 하위버튼과 연결
$sort2.addEventListener('click', () => {
const $cardList = document.getElementById('card-list');
const $cards = Array.from($cardList.children);
$cards.sort((a, b) => {
const titleA = a.querySelector('.movie-title').textContent;
const titleB = b.querySelector('.movie-title').textContent;
return titleB.localeCompare(titleA);
});
$cards.forEach(card => {
$cardList.appendChild(card);
});
});
=> 다른 팀원분의 코드로 진행하는 프로젝트 (+영화포스터, 제목 노출)이기에
-> 출력 결과 사진 첨부는 어렵지만 카드가 정렬되는 기능을 구현하는 것에 성공
dropdown
기능)카드 배열에 성공
->
dropdown
버튼의 기능이 수행되도록 다시 2차 작업 시작
// 드롭다운 버튼
<html>
<div class="dropdown">
<button class="dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">영화 제목 정렬</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item1" id="dropdown-item1" href="#" onclick="sort1">오름차순</a></li>
<li><a class="dropdown-item2" id="dropdown-item2" href="#" onclick="sort2">내림차순</a></li>
</ul>
</div>
</html>
<script>
// 드롭다운 버튼 클릭 시 이벤트 핸들러
const dropdownMenu = document.querySelector('.dropdown-menu');
const dropdownButton = document.getElementById('dropdownMenuButton1');
dropdownButton.addEventListener('click', function () {
if (dropdownMenu.style.display === 'none') {
dropdownMenu.style.display = 'block';
} else {
dropdownMenu.style.display = 'none';
}
});
// 드롭다운 항목 클릭 시 이벤트 핸들러
// console.log 오류 방지 + 버튼 작동 확인
const dropdownItems = document.querySelectorAll('.dropdown-item1, .dropdown-item2');
dropdownItems.forEach(item => {
item.addEventListener('click', function (event) {
event.stopPropagation(); // 이벤트 전파 중지
const text = this.textContent;
console.log(`Item ${text} clicked`);
});
});
// 클릭 이벤트가 발생한 곳 이외의 영역을 클릭하면 메뉴를 닫음
document.addEventListener('click', function (event) {
const dropdownMenu = document.querySelector('.dropdown-menu');
const dropdownToggle = document.querySelector('.dropdown-toggle');
if (!dropdownToggle.contains(event.target) && !dropdownMenu.contains(event.target)) {
dropdownMenu.style.display = 'none';
}
});
// 페이지 로드 시 메뉴 상태를 복원
// 원래는 구상 예정X, 하지만 페이지 새로 고침시
// ->
// 메뉴 버튼을 누르지 않아도 하위 메뉴가 생성되는 오류가 있기에 추가
window.addEventListener('load', function () {
const menuState = localStorage.getItem('menuState');
if (menuState === 'on') {
dropdownMenu.style.display = 'block';
} else {
dropdownMenu.style.display = 'none';
}
});
</script>
dropdown
버튼 실행 확인 완료된 코드js
로 기능을 구현하느라 시간을 지체하여
->css
는 다음 기회에 개인적으로 구현해보기로 결심했다.
<html>
<a/>
:
<li/>
:
href
:
href = "#"
:
일반적으로 클릭 시 아무 동작도 수행하지 않고
-> 페이지의 위치를 변경하지 않는 링크
주로 클릭 이벤트를 처리하기 위한 뼈대
-> js 코드로 동작 구현 가능
= 일반적:
const link = document.querySelector('a');
link.addEventListener('click', function(event) {
event.preventDefault(); // 기본 동작 방지
// 클릭 이벤트 처리 코드 작성
});
sort
(메서드):
js의 배열의 내용을 정렬
호출 시 배열의 요소들이 문자열로 취급되어 정렬
=> 정렬은 원본 배열을 변경 -> 변경된 배열로 전환
오름차순 (a - b)
내림차순 (b - a)
array.sort(compareFuntion);
array
:
compareFunction
(선택 사항):
const numbers = [5, 1, 3, 2, 4];
numbers.sort(); // 기본적으로 문자열로 변환하여 사전식으로 정렬
console.log(numbers); // [1, 2, 3, 4, 5]
const words = ['banana', 'apple', 'cherry'];
words.sort(); // 문자열로 변환하여 사전식으로 정렬
console.log(words); // ['apple', 'banana', 'cherry']
const points = [40, 100, 1, 5, 25];
points.sort((a, b) => a - b); // 숫자 오름차순 정렬
console.log(points); // [1, 5, 25, 40, 100]
반환 값 < 0
=> 첫 번째 요소가 두 번째 요소보다 앞에 정렬
반환 값 = 0
=> 요소 정렬X
반환 값 > 0
=> 첫 번째 요소는 두 번째 요소보다 뒤에 정렬
const $movie_title = document.querySelectorAll('.movie-title');
:
= 문서 내에서 모든 클래스의 이름이 'movie-title'인 요소들을 선택
-> '$movie_title' 변수에 할당하는 역할
$movie_title
(변수 이름):
NodeList
'.movie-title'
:
forEach
(메서드):
배열
/ NodeLis
t와 같은 반복 가능한 매체
에서 사용 가능콜백 함수
실행EX.
dropdownItems
에 대해forEach
메서드를 사용하여 각 항목에 이벤트 리스너 추가dropdownItems.forEach(item => { item.addEventListener('click', function (event) { event.stopPropagation(); // 이벤트 전파 중지 const text = this.textContent; console.log(`Item ${text} clicked`); }); });
addEventListener
(메서드):
요소
에 이벤트 리스너
추가EX.
dropdownButton
요소에클릭 이벤트 리스너
를추가
하고, 클릭 이벤트가 발생할 때마다 함수가 실행dropdownButton.addEventListener('click', function () { if (dropdownMenu.style.display === 'none') { dropdownMenu.style.display = 'block'; } else { dropdownMenu.style.display = 'none'; } });
querySelectorAll
:
CSS 선택자
에 일치
하는 모든 요소 NodeList
로 반환EX.
const dropdownItems = document.querySelectorAll('.dropdown-item1, .dropdown-item2');
querySelector
:
문서 내에 지정
된 CSS 선택자에 일치
하는 첫 번째 요소 반환
EX.
const dropdownMenu = document.querySelector('.dropdown-menu');
getElementById
(메서드):
id 속성값
에 해당하는 요소
를 반환
고유한 id를 가진 요소를 선택
할 때 사용style.display
:
display
속성을 설정하거나 가져올 수 있는 속성.EX. 드롭다운 메뉴 설정
dropdownMenu.style.display === 'none' dropdownMenu.style.display = 'block'
none
text
박스가보여지지 않음
block
text
박스가아래로 보여짐
menuState
(변수):
로컬 스트로리지
에서 메뉴 상태
저장
EX.
localStorage.getItem('menuState')
을 사용하여menuState
키에 저장된 값을 가져옵니다.window.addEventListener('load', function () { const menuState = localStorage.getItem('menuState');
localStorage.getItem
(메서드):
로컬 스토리지
에서 주어진 키에 해당하는 값을 가져옴EX.
menuState
키에 저장된 값을 가져옴const menuState = localStorage.getItem('menuState');