javascript 웹 페이지 메인 이미지(visual) 영역 만들기
예시로 만든 코드는 3가지 이미지로 3초마다 이미지가 한 장씩 바뀌며, 버튼을 눌렀을 때 해당 이미지로 이동한다.
그리고 이전, 다음 버튼을 누르면 이전, 다음 이미지를 보여준다.
오늘 내가 배운 것
1. DOMContentLoaded
2. 고차 함수 (higher-order function)
3. getAttribute()
1. DOMContentLoaded
DOMContentLoaded는 전체에 한 번만 실행된다.
DOMContentLoaded 이벤트를 사용하는 이유는 코드가 실행됐을 때 `script` 태그의 위치가 `head` 안에 있다면 스크립트를 실행될 때 HTML을 다 불러들이 후에 실행시키기 위해서 사용한다. DOMContentLoaded 이벤트를 안 쓰고 script 태그를 `/body` (body의 마지막 닫는 태그) 바로 앞에 사용하면 된다.
2. 고차 함수 (higher-order function)
//내가 클릭한 버튼이 몇 번째 버튼인지를 알기 위해 작성
function fn(index) {
return function (e){
console.log(index, e)
}
}
//addEventListener의 장점 : 함수 하나로 여러 엘리먼트에게 이벤트 등록이 가능하다.
Element.addEventListener("click", fn(1)) // 인덱스1일때 (1번버튼 일때)
함수를 인자로 받거나 또는 함수를 직접 리턴함으로써 작동 하는 함수를 `고차함수(higher-order function)`라 한다. 이 때, 다른 함수의 인자로 전달되는 함수를 '콜백 함수'라고 부른다.
3. getAttribute()
<input type="text" />
const input = document.querySelector("type") // result : text
element.getAttribute(qualifiedName:string)
엘리먼트 뒤에 쓰는 메서드이고 속성을 문자열로 적으면 그 속성에 해당하는 값을 문자열로 리턴해준다. 값이 없으면 null
Element.getAttribute()와 indexOf 비교
getAttribute의 패턴이 linear search (indexOf) 와 같다
linear search 배열의 요소를 하나씩 검사하면서 target과 같은 값의 인덱스 값을 출력해준다.
linear search는 반복을 해서 인덱스 값을 결과로 보여주지만, getAttribute()는 반복을 해서 값을 직접적으로 문자열로 보여준다.
방법이나 과정은 같지만 목적(결과)가 다르기 때문에 원하는 걸 알맞게 잘 찾아 써야 한다.
기본적으로 3초에 한 이미지씩 보여주고, 버튼을 누르면 1은 1번 이미지 2는 2번 이미지 3은 3번 이미지를 보이고, 이전, 다음 버튼을 이용해서 이미지도 바꿀 수 있다. 이미지를 바꾸는 과정에서 누르는 버튼에 따라서 인터벌 시작점도 바뀐다.
HTML
<!DOCTYPE html>
<html lang="en">
<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>
<link href="./public/css/index.css" type="text/css"rel="stylesheet"/>
<script src="./public/js/last.js" type="text/javascript"></script>
</head>
<body>
<ul id="visual">
<li style="background: darkcyan;">1</li>
<li style="background: gray;">2</li>
<li style="background: green;">3</li>
</ul>
<ul id ="visualBtn">
<li><button>버튼1</button></li>
<li><button>버튼2</button></li>
<li><button>버튼3</button></li>
</ul>
<ul id="side_btn">
<li id="prev_btn" class="prev"><button>이전</button></li>
<li id="next_btn" class="next"><button>다음</button></li>
</ul>
</body>
</html>
CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul,li{
list-style: none;
}
body {
margin-top: 50px;
}
#visual {
position: relative;
width: 1900px;
height: 500px;
margin: 0 auto;
overflow: hidden;
}
#visual > li {
position: absolute;
transition: all 3s;
opacity : 0;
height: 500px;
width: 1920px;
text-align: center;
font-size: 400px;
}
#visualBtn > li {
text-align: center;
margin: 40px;
}
button{
width: 200px;
height: 50px;
font-size: 40px;
}
#visual > li.on {
opacity: 1;
}
#side_btn{
display: flex;
justify-content: space-between;
margin: -180px 0 0 0;
}
#prev_btn{
margin-left: 50px;
}
#next_btn{
margin-right: 50px;
}
JavaScript
let count = 0
let intervalId = 0
function init() {
const imgs = document.querySelectorAll("#visual > li")
const btns = document.querySelectorAll("#visualBtn > li")
const prevBtn = document.querySelector(".prev")
const nextBtn = document.querySelector(".next")
function findIndex(){
for(let i=0 ; i < imgs.length; i++){
if(imgs[i].getAttribute("class") === "on")return i
}
}
function slide(){
let prev = count === 0 ? imgs.length - 1 : count - 1
imgs[count].className ="on"
imgs[prev].className = ""
if(++count === 3) count = 0
}
function btnHandler(index){
return function(e) {
clearInterval(intervalId)
const current = findIndex()
imgs[current].className =" "
imgs[index].className = "on"
count = index
intervalId = setInterval (slide, 3000)
}
}
function prevBtnHandler(e){
clearInterval(intervalId)
const current = findIndex()
let index = current === 0 ? imgs.length -1 : current -1
imgs[current].className = ""
imgs[index].className = "on"
count = index
intervalId = setInterval (slide, 3000)
}
function nextBtnHandler(e){
clearInterval(intervalId)
const current = findIndex()
let index = current === 2 ? 0 : current +1
imgs[current].className = ""
imgs[index].className = "on"
count = index
intervalId = setInterval (slide, 3000)
}
for(let i=0; i<btns.length; i++){
btns[i].addEventListener('click', btnHandler(i) )
}
prevBtn.addEventListener('click',prevBtnHandler)
nextBtn.addEventListener('click',nextBtnHandler)
slide()
intervalId = setInterval (slide, 3000)
}
document.addEventListener("DOMContentLoaded", init)
'시작 > TIL(Today I Learned)' 카테고리의 다른 글
221114 실전예제 - 로또 번호 생성기 (0) | 2022.11.15 |
---|---|
221114 실전예제 - 웹페이지 MENU 만들기, 슬라이드 영역만들기 (0) | 2022.11.14 |
221110 JavaScript - setTimeout과 setInterval, 동기와 비동기, 싱글스레드,이벤트 루프(event loop) (0) | 2022.11.11 |
221109 JavaScript - form을 이용한 이벤트활용 (1) | 2022.11.10 |
221108 JavaScript - 이벤트 (EVENT) (0) | 2022.11.09 |
댓글