자기소개 페이지 중 자바스크립트를 활용하여 동적 기능을 구현한 두번째 부분에 대해 소개하려고 합니다.
전체 소스코드
자기소개 페이지
첫번째 기능 - Slide
세번째 기능 - Light/Dark mode
두번째는 자기소개 페이지의 색상 테마를 바꿀 수 있는 기능입니다.
밋밋할 수 있는 페이지를 다채롭게 바꿔보자 다음 기능을 적용해봤습니다.
HTML
코드는 다음과 같습니다.우선 톱니바퀴 모양의 버튼은 icons8
의 아이콘을 참조했습니다.
이 톱니바퀴 버튼은 9가지 색상을 담은 <div class="control__colors"> </div>
를 보여주고 없애주는 역할을 수행합니다.
실질적으로 색상을 선택하는 <div class="control__colors"> </div>
의 자식 요소는 자바스크립트를 활용하여 HTML요소를 추가하였습니다. (자바스크립트 코드를 확인해주세요!)
<div class="controller">
<div class="theme-color">
<button class="color-btn">
<img class="color-controller"
src=icons8_톱니바퀴_이미지./>
</button>
<div id="jsColors" class="control__colors visible">
<!--
<div class="controls__color" style="background: ${color} "}> </div>
-->
</div>
</div>
</div>
css
코드입니다..controller
선택자의 자식요소로는 .theme-color
와 .mode-changer
두개가 있다는 점을 참고해주세요. 후자의 선택자에 대해서는 다음 포스팅에서 알아보겠습니다.아래 사진은 .controller
선택자만 position: absolute
값을 가진 상태의 모습입니다.
주요 정보를 담은 .container
역시 body
태그를 참조하기 때문에 위치가 왼쪽으로 치우쳐있으며,
색상을 선택하는 .control__colors
는 .controller
의 하단에 위치합니다.
position: absoulte
값을 가진 선택자는 position: relative
값을 가진 선택자의 위치를 참조합니다.
저는 위 사진 속 요소들을 배치할 때 relative
값을 상위 선택자에 설정하지 않았기 때문에 position: relative
값은 body
태그를 참조합니다.
(.container
의 다른 자식 요소들의 코드를 보시면 relative
값이 추가 된 선택자가 있습니다. 이 선택자의 자식 요소에 absolute
값을 추가하면 body
태그가 아닌 부모 요소의 위치를 참조하게 됩니다.)
.controller {
position: absolute;
top: 0;
right: 0;
margin-top: 10px;
display: flex;
justify-content: space-evenly;
align-items: center;
width: 300px;
}
.theme-color button {
border: none;
outline: none;
background: inherit;
padding: 5px;
cursor: pointer;
}
.theme-color button:hover {
transform: scale(calc(1.2));
}
.control__colors {
display: flex;
position: absolute;
top: -50px;
left: -50px;
background: #d5d5d5;
padding: 10px;
border-radius: 5px;
}
.control__colors .controls__color {
width: 20px;
height: 20px;
margin: 0 5px;
border-radius: 50%;
cursor: pointer;
transition: 0.3s ease;
}
.control__colors .controls__color:hover {
transform: scale(calc(1.3));
}
다음은 자바스크립트 코드입니다.
Color Theme
을 통해 색상을 바꿀 요소는 다음과 같습니다.
1. 각 페이지의 제목 → title
2. 각 페이지를 선택하는 navigation 항목 → navList
3. 주요 정보를 담고 있는 .container 선택자의 테두리 → containerDiv
4. 기술란의 퍼센트를 보여주는 .skill--bar 선택자의 색상 → skillBar
5. Dark/Light모드를 설정할 수 있는 버튼 → sliderBtn
6. side section과 main section을 구분하는 선 → sideSec
이벤트를 추가해야 하는 요소는 다음과 같습니다.
1. 9가지 색상을 담는 요소 → pallete
2. pallete를 나타내고 없애주는 톱니바퀴 버튼 → btn
const title = document.querySelectorAll(".main--title");
const navList = document.querySelectorAll(".nav--list");
const containerDiv = document.querySelector(".container");
const skillBar = document.querySelectorAll(".skill--bar");
const sliderBtn = document.querySelector(".slider.round");
const sideSec = document.querySelector(".side--section");
const pallete = document.querySelector(".control__colors");
const btn = document.querySelector(".color-btn");
COLOR_THEME
배열에 9가지 색상을 담아주었습니다.
palletMaker(color)
함수는 div 요소를 반환하는 함수입니다.
color라는 파라미터를 받아오는데 위에서 언급했던 COLOR_THEME
의 각각의 원소를 받아옵니다.
반환되는 div 요소들은 pallete
의 자식 요소에 생성됩니다.
btn
에 onclick
이벤트를 설정해줍니다.
pallete
의 클래스에 visible
이라는 클래스의 여부를 확인해줍니다.
visible
클래스는 display: none;
이라는 값을 가지고 있는데, invisible
로 수정해야될 것 같습니다.
btn
을 클릭하였을 때 visible
클래스가 포함되어 있다면, 그 클래스를 지우고 내부 HTML에 배열의 내장함수 map을 이용하여 COLOR_THEME
의 갯수만큼 div 요소를 자식 요소로 반환하여 줍니다.
btn
을 클릭하였을 때 visible
클래스가 포함되어 있지 않다면, 클래스를 추가하여 위의 요소를 숨겨줍니다.
const COLOR_THEME = [
"#2c2c2c",
"#e2e2e2",
"#ff3b30",
"#ff9500",
"#ffcc00",
"#4cd963",
"#5ac8fa",
"#0579ff",
"#5856d6",
];
function palletMaker(color) {
return `<div class="controls__color" style="background: ${color} "}> </div>`;
}
btn.onclick = () => {
const classCheck = pallete.classList.contains("visible");
if (classCheck) {
pallete.classList.remove("visible");
pallete.innerHTML = COLOR_THEME.map((item) => palletMaker(item)).join("");
} else {
pallete.classList.add("visible");
}
};
자바스크립트 코드 상단에서 접근한 Html 요소들에 대해 style을 바꾸어줍니다.
처음에는 자바스크립트를 통해 추가한 html요소 접근에 애를 먹었습니다.
document.addEventListner("click", callback Function)
(아래의 코드와 동일) 위의 방법은 document의 모든 부분에서 click 이벤트가 발생합니다.
발생한 이벤트 중 e.target.className
이 .controls__color
선택자를 가리키는 요소만 선택되도록 조건문을 작성하였는데요.
1) 문서 전체의 모든 부분을 클릭할 수 있으면서,
2) 선택자가 .controls__color
로 조건이 충족되는 경우
→ Html 요소의 style
을 바꿀 수 있도록 조건문과 실행 코드를 작성해주었습니다.
동일한 클래스를 가진 요소들은 document.querySelectorAll()
을 통해 NodeList로 반환됩니다.
반환된 요소들은 배열의 index 값에 접근할 수 있는 반복문을 통해 style
을 제어하는 함수로 구분해주었습니다.
function colorChanger(e) {
const PAINT = "controls__color";
const color = e.target.style.backgroundColor;
if (e.target.className === PAINT) {
sideSec.style.borderRight = `1px solid ${color}`;
sliderBtn.style.backgroundColor = color;
containerDiv.style.boxShadow = `0 3px 10px ${color}, 0 1px 3px ${color}`;
navListTitleColor(color);
skillBarColor(color);
} else {
console.log("please click the pallet");
}
}
document.addEventListener("click", colorChanger);
function navListTitleColor(color) {
for (let i = 0; i < navList.length; i++) {
navList[i].style.color = color;
// title과 navList의 length가 동일하여 같은 반복문에 작성
title[i].style.color = color;
}
}
function skillBarColor(color) {
for (let i = 0; i < skillBar.length; i++) {
skillBar[i].style.backgroundColor = color;
}
}
1. css 선택자 중 .visible
클래스 이름 바꾸어주기 (2022-05-16부 완료)
2. javascript 중 document.addEventLisnter
대신 palletMaker()
함수 실행 이후에 DOM
접근 해보기
palleteMaker()
함수가 실행된 조건문 내부에서 접근이 가능한 것을 알았습니다.
const paint = document.querySelector(".controls__color");
console.log(paint);
콘솔창의 결과는 아래와 같이 동적으로 추가된 요소에 접근이 가능했습니다.
하지만 조건문 내부에 다시 조건문을 적게 되고, 다시 onclick함수를 반복해서 적어야했습니다.
좀 더 공부를 해본 다음 더 효울적인 방법으로 접근을 해야될 것 같습니다😂