

✔️ 아이콘 사용할 수 있는 링크
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog=="
crossorigin="anonymous"
/>
✔️ 사용 방법
italic 태그를 사용하여 아이콘을 넣을 수 있다.
클래스 지정만 해주면 알아서 아이콘이 들어간다.
<i class="fab fa-twitter fa-3x"></i>
<i class="fab fa-youtube fa-3x"></i>
<i class="fab fa-facebook fa-3x"></i>
@import url("https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap");
:root {
font-family: Roboto Mono
}
✔️ before
#container {
box-shadow: inset 0 0 10px red;
display: flex;
justify-content: center;
gap: 100px;
}
.item-container {
box-shadow: inset 0 0 10px green;
flex-basis: 200px;
color: white;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
gap: 10px;
}
이렇게 초록색 아이템 박스들을 가장 큰 빨간색 컨테이너 안에 넣고, 각 아이템 박스들을 flex로 처리했다.
이때 flex로 처리한 이유는 여러 이유가 있지만,
margin을 주는 것보다 gap을 주는 것이 더 편하겠다고 느낌flex-basis를 사용하여 창의 너비가 줄어들면 flex-shrink로 각 아이템의 너비가 줄어들게 하고 싶음중에 2번 이유가 더 커서 각 아이템 박스를 flex로 처리했는데, item-container { flex-basis: 200px } 속성이 적용되지가 않았다.
👀 왜
flex item에flex-basis가 적용 안되었을까?부모 (
flex-container)에 너비를 지정하지 않았기 때문이다.
flex-basis는 주어진 공간에서 각 flex item이 차지할 기본 너비를 설정하지만, 이 값이 제대로 작동하려면 부모 요소(flex container)가 공간을 명확히 정의해야한다.
✔️ after
#container {
box-shadow: inset 0 0 10px red;
⭐️ width: 100%; ⭐️
display: flex;
justify-content: center;
gap: 100px;
}
.item-container {
box-shadow: inset 0 0 10px green;
flex-basis: 200px;
color: white;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
gap: 10px;
}
부모 요소에 너비를 100%으로 설정하여 flex item에게 공간을 할당해준다.
이 공간안에서 flex-basis, flex-shrink, flex-grow 등이 이루어지는 것이다.
🎯 flex 속성 사용 시, 부모에게 공간 할당은 필수이다!!
내가 생각했던 방식은 counter라는 모든 클래스를 가져와서 forEach 함수를 사용해 각각의 최댓값을 인덱스로 묶어주고 카운팅을 하는 것이었다.
✔️ before
let counters = document.querySelectorAll(".counter");
const maxValues = [12000, 5000, 7500];
counters.forEach((counter, idx) => {
for(let i= 0; i < maxValues[idx]; i++) {
counter.textContent = i;
}
});
접근법은 좋았지만 내가 한 방식대로면 그냥 최댓값이 바로 출력되고 카운팅이 되는 모습이 화면에 나타나지 않았다.
for 루프 내에서 counter.textContent를 반복적으로 업데이트하기 때문에 최종적으로는 마지막 값만 표시된다.
👀 그러면 이 방식은?
그 다음으로 든 의문은, 그렇다면 반복문이 너무 빠르게 흘러가서 내가 원하는대로 진행은 되지만 결국 마지막 값만 남은 것 아닌가?
그래서 나는 이 반복문을 함수로 처리하고, setTimeout 을 이용하여 함수를 실행시키는 속도를 조절했다.
✔️ before
let counters = document.querySelectorAll(".counter");
const maxValues = [12000, 5000, 7500];
counters.forEach((counter, idx) => {
const updateCounter = () => {
for (let i = 0; i <= maxValues[idx]; i++) {
counter.textContent = i;
}
};
setTimeout(updateCounter, 1);
updateCounter();
});
이렇게 진행하면 될 것 같았으나 결국 또 똑같은 결과가 나왔다.
자세히 생각해보니, 함수를 실행시키는 속도에 제어를 걸어도 함수 안에서 진행되는 for문이 돌아가는 속도는 내가 조절할 수가 없다.
이 for문이 너~무 빠르게 진행이 되니까 함수를 천천히 호출한다고 해도 결국 함수가 호출될때마다 마지막 값만 출력이 되는 것이다.
그래서 포기하고 다른 방식을 찾았다.
✔️ after
let counters = document.querySelectorAll(".counter");
const maxValues = [12000, 5000, 7500];
counters.forEach((counter, idx) => {
let count = 0; // 카운트 초기화
const increment = Math.ceil(maxValues[idx] / 200); // 매 프레임 증가 값 설정
const updateCounter = () => {
if (count < maxValues[idx]) {
count += increment;
console.log(count);
if (count > maxValues[idx]) {
count = maxValues[idx];
}
counter.textContent = count;
setTimeout(updateCounter, 1); // if 안에 넣어 최댓값에 도달 안했을 때만 함수 호출
}
};
updateCounter();
});
이 방식은 값을 증가시키는 함수를 만들고, 그 함수를 시간마다 호출하는 것이다.
전역 변수 (ForEach 안에서 전역변수라고 치겠다)로 count를 설정해두고 함수가 호출될 때마다 이 카운트는 증가하므로 함수가 호출될때마다 값이 변하고 화면에 출력된다.
그리고 이 방식을 진행하면 아까 내가 원했던 대로 함수를 원하는 시간마다 호출할 수 있다는 점이다.
아까는 for이라는 반복문 때문에 함수를 호출하는 시간은 내가 조절 했으나 함수를 호출할 때마다 얘가 미친듯이 돌아갔다면 이번엔 내가 함수를 호출할때마다 함수 안에서 이 작업이 한번씩만 일어날 수 있었다.
const increment = Math.ceil(maxValues[idx] / 200);
최댓값을 나눠서 얼만큼 증가시킬 것인지 정할 수 있다.
결국 if (count < maxValues[idx]) 라는 조건문 때문에 위의 증가값을 어떻게 설정하는지에 따라 함수가 호출되는 횟수가 다르다.
증가값 크게 설정하면 - 빠르게 최댓값에 도달 - 호출 횟수 줄어들음 - 빠르게 끝남
증가값 작게 설정하면 - 느리게 최댓값에 도달 - 호출 횟수 늘어남 - 느리게 끝남
따라서 밑의 빈칸의 역할이 중요하당 (증가값과 반대임 --> 저 값이 작아져야 증가값이 커지니까) (나누는 수 이므로)
const increment = Math.ceil(maxValues[idx] / ⭐️ 함수 호출 횟수 조절!!⭐️ );
setTimeout과 setInterval은 둘 다 JavaScript에서 비동기적으로 코드를 실행하기 위한 타이머 함수이지만, 동작 방식이 다르다.
| setTimeout | setInterval | |
|---|---|---|
| 사용 방법 | setTimeout(function, delay) | setInterval(function, interval) |
| 매개변수 | delay: 밀리초 단위의 지연 시간 | interval: 밀리초 단위의 실행 간격 |
| 실행 횟수 | 한번만 실행 | 반복 실행 |
| 작동 방식 | 지정된 시간이 지난 후 한번만 함수를 실행 | 지정된 시간 간격마다 반복해서 함수를 실행 |
| 중지 방법 | clearTimeout() | clearInterval() |