let currentIndex = 0; // 현재 이미지 위치
$next.addEventListener('click', () => {
// 현재 내가 보고 있는 이미지가 배열의 0번 인덱스라면
// 다음버튼을 누르면 1번을 보여줘야 한다.
currentIndex = (currentIndex + 1) % images.length;
$img.setAttribute('src', images[currentIndex]);
});
$prev.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + images.length) % images.length;
$img.setAttribute('src', images[currentIndex]);
});
console.log(e);
를 통해 확인 가능!<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.root {
width: 300px;
height: 300px;
background: red;
}
.parent {
width: 200px;
height: 200px;
background: green;
}
.child {
width: 100px;
height: 100px;
background: blue;
}
.target {
width: 50px;
height: 50px;
background: black;
}
</style>
</head>
<body>
<div class="root">
<div class="parent">
<div class="child">
<div class="target"></div>
</div>
</div>
</div>
<script>
document.querySelector('body').onclick = e => alert('body');
document.querySelector('.root').onclick = e => alert('root');
document.querySelector('.parent').onclick = e => alert('parent');
document.querySelector('.child').onclick = e => {
e.stopPropagation();
alert('child');
};
document.querySelector('.target').onclick = e => {
// 버블링 방지 : 이벤트 전파 중단
e.stopPropagation();
alert('target');
};
</script>
</body>
</html>
target, child, parent, root, body
순서로 나오게됨 (버블링!)stopPropagation()
를 이용하면 버블링을 중단시킬 수 있음!matches()
: 조건부로 이벤트를 중단시키는 것 가능// 태그에서 class=active를 제거하는 함수
const removeActive = () => {
[...$fruits.children].forEach($li => {
if ($li.classList.contains('active')) {
$li.classList.remove('active');
return;
}
});
};
// 부모에 이벤트
$fruits.addEventListener('click', e => {
// 이벤트 중단 : 조건부로 이벤트를 중단시키는 것 (matches 이용)
// 클릭한 이벤트가 li가 아니라면?
if (!e.target.matches('#fruits li')) {
return; // 중단하겠다.
}
// console.log(e.target); // 이벤트가 터진 태그를 알기위함
// 1. active 클래스 제거
removeActive();
// 2. 클릭대상에 active 클래스 부여
e.target.classList.add('active');
// 3. 클릭한 태그의 텍스트를 em.msg에 저장
// e.target.textContent = 클릭한 태그의 텍스트
document.querySelector('.msg').textContent = e.target.textContent;
});
$btn.addEventListener('click', () => {
$fruits.innerHTML += `<li id="${$input1.value}">${$input1.value}</li>`
});
});
// 1. 추가 버튼을 클릭하면
// 1-1. 추가 버튼 요소 노드를 가져온다
// const $addBtn = document.getElementById('add');
// const $input = document.querySelector('.text-box');
// // 1-2. 버튼에 클릭 이벤트 부여
// $addBtn.addEventListener('click', e => {
// // 2. 입력한 텍스트를 읽어서
// // 2-1. input태그를 가져옴
// const inputText = $input.value;
// // 3. LI태그로 만들어서 텍스트를 넣고
// // 3-1. LI태그 만들기
// const $newLi = document.createElement('li');
// // 3-2. 텍스트 넣기
// $newLi.textContent = inputText;
// // 4. 아이디를 부여 한 후
// $newLi.setAttribute('id', inputText);
// // 5. UL에 추가한다.
// $fruits.appendChild($newLi);
// // 6. input 비우기
// $input.value = '';
// })
// input에 텍스트를 입력하고 엔터를 누르면 추가 버튼을 클릭하게 함
// 1. Input에 키보드 이벤트를 건다
$input1.addEventListener('keyup', e => {
if (e.key === 'Enter') {
$btn.click();
}
});
document
)에서 시작하여 이벤트 타깃에 도달할 때까지 내려감addEventListener
함수에 세 번째 인자로 true
값을 주어야 합니다.element.addEventListener('click', function(event) {
// 핸들러 로직
}, true); // 캡처링 단계에서 이벤트를 처리하기 위해 true 값을 설정
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a id="link" href="https://github.com">깃허브로 이동</a>
<form id="my-form" action="https://www.google.com">
<input type="text" placeholder="이메일을 쓰세요.">
<button type="submit">확인</button>
</form>
<script>
const $link = document.getElementById('link');
$link.addEventListener('click', e => {
if (!confirm('깃허브로 이동합니까??')) {
e.preventDefault(); // 태그의 기본 자바스크립트 기능 중지
}
});
const $form = document.getElementById('my-form');
$form.addEventListener('submit', e => {
e.preventDefault(); // 기본 submit기능 해제
if ($form.firstElementChild.value === '') {
return;
}
console.log('양식을 서버에 제출함');
$form.submit();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
#slider {
display: flex;
align-items: center;
background-color: white;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
border-radius: 10px;
overflow: hidden;
}
#slider img {
max-width: 400px;
max-height: 300px;
display: block;
object-fit: cover; /* background-size : cover의 image 버전 */
}
button {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #0056b3;
}
button:focus {
outline: none;
}
#thumbnails {
display: flex;
justify-content: center;
gap: 10px;
}
.thumbnail {
width: 100px;
height: 75px;
object-fit: cover;
cursor: pointer;
transition: opacity 0.3s ease;
border-radius: 5px;
}
.thumbnail:hover {
opacity: 0.7;
}
</style>
</head>
<body>
<div id="slider">
<button id="prev">이전</button>
<img
id="image"
src="https://blog.kakaocdn.net/dn/dN4uhe/btr8xWDwbrK/5YjBrelhtJwU2BAcLtEVoK/img.jpg"
style="width: 400px; height: auto"
/>
<button id="next">다음</button>
</div>
<!-- 모든 이미지의 썸네일을 슬라이더 하단에 배치 -->
<div id="thumbnails"></div>
<script>
// 이미지 경로를 저장할 배열
const images = [
"https://blog.kakaocdn.net/dn/dN4uhe/btr8xWDwbrK/5YjBrelhtJwU2BAcLtEVoK/img.jpg",
"https://img.koreanairdfs.com/upload/prd/542/20190917114040414002.png",
"https://www.sisajournal.com/news/photo/202108/222572_131065_5150.jpg",
"https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8fA%3D%3D",
];
// 배열의 길이만큼 img태그를 만들어서 #thumbnails에 추가
const $thumbnailContainer = document.getElementById("thumbnails");
images.forEach((imgSrc, i) => {
const $sliderImg = document.createElement("img");
$sliderImg.setAttribute("src", imgSrc);
$sliderImg.setAttribute("alt", "iamge${i+1}");
$sliderImg.classList.add("thumbnail");
// 데이터속성에 인덱스를 담아서 추가
$sliderImg.dataset.index = i;
$thumbnailContainer.appendChild($sliderImg);
// 이런 코드가 나옴
// <img src="https://blog.kakaocdn.net/dn/dN4uhe/btr8xWDwbrK/5YjBrelhtJwU2BAcLtEVoK/img.jpg"
// alt="iamge${i+1}" class="thumbnail" data-index="0">
});
let currentIndex = 0; // 현재 이미지 위치
// 이전, 다음 버튼 클릭 이벤트
const [$prev, $sliderImg, $next] = [
...document.getElementById("slider").children,
];
// 이미지와 인덱스를 업데이트하는 함수
const updateImage = (index) => {
currentIndex = index;
$sliderImg.setAttribute("src", images[currentIndex]);
};
$next.addEventListener("click", () => {
updateImage((currentIndex + 1) % images.length);
// if(currentIndex >= images.length) currentIndex = 0;
// currentIndex++;
});
$prev.addEventListener("click", () => {
updateImage((currentIndex - 1 + images.length) % images.length);
// currentIndex--;
// if (currentIndex < 0) {
// currentIndex = images.length - 1;
// }
});
// 이미지 썸네일 컨테이너에 클릭이벤트 바인딩
$thumbnailContainer.addEventListener('click', e => {
const clickedIndex = +e.target.dataset.index;
updateImage(clickedIndex);
});
</script>
</body>
</html>
display: flex;
가 걸려있기 때문에 수평으로 되어있는 것을 확인했다. 그래서 body에 flex-direction: column;
을 주어서 수직으로 만들어 줌!