💥display: flex; 속성은 요소를 유연한 박스 모델로 만들어 준다. 이를 통해 요소들을 가로 또는 세로로 나열할수 있는데
display: flex; 를 적용한 부모 요스는 flex container가 되고 그리고 그 안에 있는 자식 요소들은 flex-items가 된다. flex container는 자식 요소들을 가로 또는 세로로 나열하는 레이아웃을 생성한다.
기본적으로 flex-direction 속성은 row로 설정되어 있다. 이는 요소들을 가로로 나열하도록 지정하는 것을 의미한다. 만약 flex-direction : column을 지정한다면 요소들은 세로로 나열된다. align items:center와 flex-direction: center는 세로 정렬을 할때 같이 한쌍으로 쓰인다
💥 align-items:center 는 flex-direction: column 과 함께 사용될때 수직 방향(세로)으로 요소들을 중앙 정렬한다.
flex -direction : column 은 요소들을 세로로 나열하도록 지정하는 속성이다. 이 속성을 사용하면 요소들이 위에서 아래로 세로 방향으로 배치된다.
align-items: center; 는 세로 방향(수직)으로 요소들을 정렬할때 요소들을 수직 축에서 중앙에 정렬하는 역할을 한다. 즉 같이 사용하면 요소들이 수직 방향에서 정중앙에 위치하게 됨
이는 수직축에서 정중앙을 기준으로 요소들을 배치하는 개념 요소들이 수직 축의 중앙에 위치하게 되는 것이다.
💥 justify content: center는 flex 컨테이너 내에서 flex 아이템을 수평 방향(가로)으로 중앙에 정렬해준다.
💥 display: flex; 속성은 요소를 유연한 박스 모델로 만들어 줍니다. 그러므로 display: flex; 속성은 부모 요소에 적용됩니다.
.seats-container 클래스에 display: flex;를 적용하는 이유는 .seats-container를 부모 요소로 사용하여 그 안에 있는 .row 요소들을 가로로 나열하기 위해서입니다. 따라서 .seats-container는 가로 방향으로 자식 요소들을 배치할 수 있도록 display: flex;를 적용합니다.
.row 클래스에 display: flex;를 적용하는 이유는 .row를 부모 요소로 사용하여 그 안에 있는 .seat 요소들을 가로로 나열하기 위해서입니다. .row는 가로 방향으로 자식 요소들을 배치할 수 있도록 display: flex;를 적용합니다.
결론적으로, .seats-container와 .row 클래스에 모두 display: flex;를 적용하는 이유는 요소들을 가로로 나열하기 위해서입니다. 즉, .seats-container는 .row 요소들을 가로로 나열하고, .row는 .seat 요소들을 가로로 나열합니다.
위의 코드에서 dropdown.addEventListener('click', function() {...}) 부분은 dropdown 요소를 클릭했을 때 실행되는 클릭 이벤트 리스너입니다. 이 코드는 드롭다운을 토글하는 역할을 합니다.
dropdownContent.classList.toggle('show')은 dropdownContent 요소의 클래스에 'show' 클래스가 있는지 확인하고, 있으면 제거하고, 없으면 추가합니다. 이를 통해 드롭다운이 표시되거나 숨겨집니다.
'show' 클래스는 CSS에서 드롭다운을 표시하는 스타일을 정의하는 데 사용됩니다.
그 다음으로 var movies = document.querySelectorAll('.dropdown-content div')은 dropdownContent 요소 내의 모든 div 요소를 선택합니다.
이 코드는 선택 가능한 각 영화를 나타냅니다.
movies.forEach(function(movie) {...})는 선택한 각 영화 요소에 대해 반복문을 실행합니다.
이 반복문 안에는 각 영화를 클릭했을 때 실행되는 클릭 이벤트 리스너가 포함되어 있습니다.
movie.addEventListener('click', function() {...})은 각 영화 요소를 클릭했을 때 실행되는 클릭 이벤트 리스너입니다. 클릭 이벤트가 발생하면 function() {...} 안에 있는 코드 블록이 실행됩니다.
안쪽의 코드 블록에서 var selectedMovie = this.textContent은 클릭한 영화 요소의 텍스트 내용을 가져와 selectedMovie 변수에 저장합니다.
그 다음 alert('선택한 영화: ' + selectedMovie)은 선택한 영화를 알림창으로 표시하는 역할을 합니다.
마지막으로 dropdownContent.classList.remove('show')는 영화를 선택한 후에 드롭다운을 숨기기 위해 'show' 클래스를 제거합니다. 이로써 선택한 영화를 확인한 후 드롭다운이 자동으로 닫히게 됩니다.
movies.forEach(function(movie) {
movie.addEventListener('click', function() {
var selectedMovie = this.textContent;
// 선택한 영화로 드롭다운 버튼 내용 변경
dropdown.firstElementChild.textContent = selectedMovie;
// 위 코드는 영화를 선택할 때마다 selectedMovie 변수의 값을 이용하여
// dropdown 요소의 첫 번째 자식 요소의 텍스트 내용을 변경하고 있다.
dropdownContent.classList.remove('show');
});
});
이렇게 수정을 해주면 영화목록에서 영화1을 눌렀다 치면 firstElemnetChild 속성때문에 dropdown 요소의 첫번째 자식요소가 button class:dropbtn 영화목록 이 부분이 변경된다.
이제 좌석을 클릭하면 색깔이 변하게 해보자
•css
/* 선택된 좌석의 스타일 */
.seat.selected {
background-color: #ff9800; /* 원하는 색상으로 변경하세요 */
color: #fff; /* 선택된 좌석의 텍스트 색상 */
}
/* 선택되지 않은 좌석의 스타일 */
.seat {
background-color: #e0e0e0; /* 원하는 색상으로 변경하세요 */
color: #000; /* 선택되지 않은 좌석의 텍스트 색상 */
}
/* 버튼 클릭 시 드롭다운 내용 표시/숨김 스타일 */
.dropdown-content.show {
display: block;
}
💥 여기에서 this.classList.toggle('selected') 이 코드는 좌석 요소를 클릭할때마다 selected 클래스를 토글하는데 toggle 메서드는 클래스 리스트에 지정된 클래스가 이미 존재한는 경우 해당 클래스를 제거하고 존재하지 않는 경우에는 해당 클래스를 추가한다. 예) 내가 좌석을 한번 누르면 노란색이 추가되었는데 다시 누르면 원상복귀한다.
¯\_(ツ)_/¯ 또 새로 알게된 내용이 있었는데 css에서 .seat.selected 이렇게 써있는데 html 내에서는 seat만 있고 selected는 써준적이 없었는데 이게 this.classList.toggle('selected')에서 가져온것이다.
html 문서에서 좌석 요소에는 selected 클래스가 없지만 javascript 코드에서 이벤트 리스너를 등록하여 좌석을 클릭할 때마다 해당 좌석의 클래스에 selected 클래스를 추가하거나 제거하도록 설정하였다.
this 에 대해서 this.classList.toggle('selected')에서 this 는 이벤트가 발생한 요소를 참조한다. 코드에서 seats 변수로 선택한 모든 좌석 요소를 가져와 foreach 메서드로 각 좌석에 대해 이벤트 리스너를 등록하고 있다.
따라서 이벤트 리스너 내에서 this 는 각각의 좌석 요소를 가리키게 된다. 클릭 이벤트가 발생한 좌석 요소에 대해 classLisg.toggle('selected')을 호출하면 해당 좌석 요소의 클래스에 selected 클래스를 토글한다. 즉 클릭할 때마다 좌석 요소의 선택 상자가 토글되는 것이다.
let seats = document.querySelectorAll('.seat');
let countDisplay = document.getElementById('count');
let totalDisplay = document.getElementById('total');
let ticketPrice = 10000; // 한 좌석당 가격
seats.forEach(function(seat) {
seat.addEventListener('click', function() {
this.classList.toggle('selected');
let selectedSeats = document.querySelectorAll('.seat.selected');
let selectedSeatsCount = selectedSeats.length;
countDisplay.textContent = selectedSeatsCount;
let totalPrice = selectedSeatsCount * ticketPrice;
totalDisplay.textContent = totalPrice;
});
});
💥 getElementByID는 DOM(Document Object Model)에서 특정 ID를 가진 요소를 선택하기 위한 메서드 이 메서드는 ID를 통해 요소를 빠르게 찾을 수 있기 때문에 많은 요소 중에서 특정 요소를 선택할때 유용하다.
document.quertSelectorAll('seat.selected')를 사용하여 선택된 좌석들을 모두 선택한다.
selectedseatsCount 에는 선택된 좌석의 개수가 할당된다.
¯\_(ツ)_/¯여기에서 또 알게된 내용은 countDisplay.textcontent = selectedseatsCount 부분인데 DOM 요소에는 여러 가지 속성과 메서드가 내장되어 있습니다. 그 중 하나가 textContent 속성입니다. textContent속성은 해당 DOM 요소의 텍스트 내용을 나타내는 속성입니다. 따라서countDisplay.textContent는 countDisplay변수가 참조하는 DOM 요소의 텍스트 내용을 나타냅니다.
어쨌든 countDisplay.textcontent = selectedseatsCount 이를 통해 선택된 좌석의 수가 화면에 표시된다.
그리고 transform: translate(-50%, -50%)속성을 사용하여 텍스트를 정중앙으로 이동시킨다.
추가로 수정해줘야 할 부분이 생겼는데 좌석을 2개까지만 선택이 가능하게 해줄거다.
let selectedSeats = []; // 선택된 좌석 배열
seats.forEach(function(seat) {
seat.addEventListener('click', function() {
if (this.classList.contains('selected')) {
// 이미 선택된 좌석인 경우, 선택 취소
this.classList.remove('selected');
selectedSeats.splice(selectedSeats.indexOf(this), 1);
} else if (selectedSeats.length < 2) {
// 선택되지 않은 좌석이고 최대 선택 가능한 개수보다 작을 경우, 선택
this.classList.add('selected');
selectedSeats.push(this);
}
updateSelectedSeatsCount();
updateTotalPrice();
});
});
💥 나의 의문점은 이거엿다. if (this.classList.contains('selected')) { // 이미 선택된 좌석인 경우, 선택 취소 this.classList.remove('selected'); selectedSeats.splice(selectedSeats.indexOf(this), 1); 이것만 봤을때는 좌석 선택의 갯수 제한을 안해줬는데 어떻게 가능하냐고 2개까지만 선택하는게 이해가 안되었다.
gpt가 답변하는데 코드에서 if 문의 두 번째 조건인 selectedSeats.length < 2 는 선택되지 않은 좌석이고 최대 선택 가능한 개수보다 작을 때만 선택이 가능하도록 설정하는 부분이고 이 조건을 만족하지 않는 경우 즉 이미 2개의 좌석이 선택되어 있는 경우에는 새로운 좌석을 선택할수 없게 되어 있다.
updateSelectedSeatsCount();
updateTotalPrice();
});
});
function updateSelectedSeatsCount() {
let selectedSeatsCount = selectedSeats.length;
countDisplay.textContent = selectedSeatsCount;
}
function updateTotalPrice() {
let totalPrice = selectedSeats.reduce(function(total, seat) {
return total + ticketPrice;
}, 0);
totalDisplay.textContent = totalPrice;
}
위 코드는 좌석 선택 및 총 가격 업데이트를 처리하는 두 개의 함수인 updateSelectedSeatsCount()와 updateTotalPrice()를 정의
¯\_(ツ)_/¯ 여기에서 모르는 내용이 나왔는데 (reduce 메서드이다. foreach메서드랑 같이 콜백 함수 이지만 둘이 동일한 매개변수를 가지지는 않는다.)
reduce() 함수는 배열의 각 요소를 순회하면서 콜백 함수를 실행하는 고차 함수라는 것이다.
콜백 함수는 다음과 같은 형태를 가진다. function callback(previousValue, currentValue, currentIndex, array){ // 콜백 함수의 동작 }
• 'previousVaule : 이전 단계에서 반환된 값(누적값) • 'currentValue : 현재 처리 중인 요소