시작, 배속, 중지버튼으로 컨트롤하는 범위 슬라이더를 만들어보았다.
input type="range" 를 사용하였고 Vanila Js로 작성하였다.
완성한 slider는 이러하다.
See the Pen CodePen JavaScript Console Template by 윤다솜 (Dasom Yun) (@datoybi) on CodePen.
요구사항
play 버튼을 클릭시
play버튼을 처음 누른 경우
- 버튼 명이 pause로 바뀐다.
- slide가 돌면서 slide value를 업데이트 해준다.
- span 태그 안에 값을 slide value로 바꾼다.
pause에서 play를 누른경우
- slider가 멈춘다.
slide value가 100일 때
- interval을 초기화 한다.
- slider value 값을 0으로 초기화한다.
- play 버튼과 fater 버튼을 막는다.
stop 버튼을 클릭시
- interval을 초기화 한다.
- slider value 값을 0으로 초기화한다.
faster 버튼을 클릭시
- silder value가 더해지는 값들을 점차 늘린다.
- 일시정지일때 play 시키기
index.html
<div class="range-slider">
<button id="play">Play</button>
<button id="faster">Faster</button>
<button id="stop">Stop</button>
<span id="time">0</span>
<input type="range" id="slider" min="0" max="100" step="0.1" value="0" />
</div>
style.css
.range-slider {
display: flex;
justify-content: flex-start;
align-items: center;
}
span {
margin: 0 10px;
}
input[type="range"] {
-webkit-appearance: none;
overflow: hidden;
width: 100%;
height: 10px;
background: transparent;
cursor: pointer;
background: #e5e4e3;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 10px;
height: 10px;
background: #fff;
box-shadow: -100vw 0 0 100vw dodgerblue;
border: 0.1px solid dodgerblue;
cursor: pointer;
}
button {
width: 70px;
}
span {
width: 40px;
}
input의 css webkit을 일부 수정했고 display 부분인 배치 부분에 스타일을 추가했다.
index.js 구현부분
const $ = (selector) => document.querySelector(selector);
const speed = [0.1, 1, 5, 10];
const slider = (() => {
let interval;
let speedIdx = 0;
return {
setInterval: (newInterval) => {
interval = newInterval;
},
getInterval: () => {
return interval;
},
setSpeed: (idx) => {
speedIdx = idx;
},
getSpeed: () => {
return speedIdx;
},
increaseSlider: (sliderValue, speed) => {
// value가 100 이상이면 초기화
if (sliderValue >= 100) {
slider.stop();
$("#play").disabled = true;
$("#faster").disabled = true;
}
sliderValue += speed;
$("#slider").value = sliderValue;
document.querySelector("#play").innerHTML = "Pause";
},
play: (speed) => {
// pause 하고 play 눌렀을 때
if (slider.getInterval()) {
slider.pause();
return;
}
// 처음 play 눌렀을 때
const interval = setInterval(() => {
let sliderValue = Number.parseFloat($("#slider").value);
slider.increaseSlider(sliderValue, speed);
slider.setTime(sliderValue);
slider.setInterval(interval);
}, 100);
},
pause: () => {
slider.clearInterval();
$("#play").innerHTML = "Play";
},
stop: () => {
slider.pause();
$("#slider").value = 0;
$("#play").disabled = false;
$("#faster").disabled = false;
$("#time").innerHTML = "0";
},
clearInterval: () => {
clearInterval(slider.getInterval());
slider.setInterval();
},
setTime: (sliderValue) => {
$("#time").innerHTML = sliderValue;
},
};
})();
클로저와 IFFE를 이용하여 모듈화를 하였다. setter, getter를 이용하여 직접 접근을 지양했다.
대략적인 흐름은 play 버튼을 클릭했을 때 setInterval() 함수를 실행하여 1초에 특정 숫자 만큼 input range의 value를 증가시킨다.
흐르고 있을 때 play 버튼을 누르면 버튼 안의 내용이 pause로 변환되고 일시정지를 한다.
stop 버튼이 클릭되면 slide value를 0으로 만들어 초기화를 한다.
배속버튼을 누르면 빨라지다가 첫번째값으로 돌아온다.
index.js 이벤트 부분
// event
const clickEvents = {
play: () => {
slider.setSpeed(0);
slider.play(speed[0]);
},
stop: () => {
slider.stop();
slider.setSpeed(0);
},
slider: () => {
console.log($("#slider").value);
},
faster: () => {
let speedIdx = slider.getSpeed();
speedIdx = speedIdx + 1 > 3 ? 0 : speedIdx + 1;
slider.setSpeed(speedIdx);
slider.clearInterval();
slider.play(speed[speedIdx]);
},
};
$(".range-slider").addEventListener("click", (e) => {
const target = e.target.id;
if (target) {
clickEvents[target]();
}
});
버블링을 이용한 이벤트 위임을 사용했다.
이렇게 range slider를 구현해보았다. 다소 간단하지만 재미있었다.
https://github.com/datoybi/blog-posting/tree/main/range-slider
GitHub - datoybi/blog-posting: 블로그 포스팅 코드
블로그 포스팅 코드. Contribute to datoybi/blog-posting development by creating an account on GitHub.
github.com