오른쪽 슬라이딩 메뉴를 만들어본 김에 사이드 메뉴도 한번 맹글어보장.
자꾸 다른 사람이 만든 걸 가져다만 쓰려하면 정작 필요한 기본 로직 작성 능력이
늘지를 않는당.~~ 이건 큰 문제당.
역시 항상 그렇진 않지만, 한번 맹글어보면 생각처럼 어려울 건 없당.
그리고 화면으로 로직연습을 하는 건 정말 재밌게 로직 능력을 키워준당.
아래 소스를 복사/붙여넣기로 실행해 보공,(css 빼면 양도 별로 안됨!)
차분히 뽀인또를 이해한 다음에, 입맛에 맞게 수정/추가 해 보길 권장!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>사이드바 메뉴 참공</title>
<style>
#menuWrapper {
width: 200px;
text-align: center;
border: 5px solid pink;
}
.hide {
display: none;
}
.show {
display: block;
color: white;
font-weight: bolder;
}
.mmain {
cursor: pointer;
}
#menuTemp {
display: none;
}
.menu {
margin-bottom: 10px;
text-decoration: underline;
}
</style>
</head>
<body>
<button onclick="fAddMenus()">확인용 메뉴추가 버튼</button>
<hr />
<div id="menuWrapper">
<!-- 복사해서 쓸 html 템플릿, 요따구로 쓰면 꽤나 편함-->
<div id="menuTemp" class="menu">
<div class="mmain" onclick="fsubClick(this)">메뉴이름</div>
<div class="msub hide">
<ul>
<li>서브메뉴1</li>
<li>서브메뉴2</li>
<li>서브메뉴3</li>
<li>서브메뉴4</li>
</ul>
</div>
</div>
</div>
<script>
// 기본 틀
const menuWrapper = document.querySelector("#menuWrapper");
const menuTemp = document.querySelector("#menuTemp");
let curMenuNum = 0;
function fRanColor() {
return `rgb(
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)}
)`;
}
// 처음 클릭하거나, 같은 메뉴 클릭
function fSelfToggle(eDiv) {
curMenuNum = eDiv.parentElement.id.split("-")[1];
let subDiv = eDiv.nextElementSibling; // eDiv.parentElement.children[1]
let curState = subDiv.classList.contains("hide");
if (curState) {
subDiv.classList.remove("hide");
subDiv.classList.add("show");
subDiv.style.backgroundColor = fRanColor();
return;
}
subDiv.classList.remove("show");
subDiv.classList.add("hide");
}
// 다른 메뉴 클릭
function fDiffClick(eDiv) {
let subDiv = menuWrapper.querySelector(`#menu-${curMenuNum}`).children[1];
subDiv.classList.remove("show");
subDiv.classList.add("hide");
subDiv = eDiv.nextElementSibling; // eDiv.parentElement.children[1]
curMenuNum = eDiv.parentElement.id.split("-")[1];
subDiv.classList.remove("hide");
subDiv.classList.add("show");
subDiv.style.backgroundColor = fRanColor();
}
function fsubClick(eDiv) {
if (!curMenuNum || curMenuNum == eDiv.parentElement.id.split("-")[1]) {
fSelfToggle(eDiv);
} else {
fDiffClick(eDiv);
}
}
let i = 1; // 그냥 id 구분용 전역 변수
// 메뉴 추가 함수
function fAddMenus() {
const menuClone = menuTemp.cloneNode(true);
menuClone.setAttribute("id", `menu-${i}`);
menuClone.querySelector(".mmain").textContent = `메뉴${i}`;
const lis = menuClone.querySelectorAll("li");
lis.forEach((li, idx) => {
console.log(li);
li.textContent = `서브${i}-${idx}`;
});
i++;
menuWrapper.append(menuClone);
menuClone.style.display = "block";
}
</script>
</body>
</html>
나의 경우 결과는 아래와 같았당.!
위 소스가 이해 되었다면, 메뉴 구조도를 매개변수로 받아서 한번에 메뉴를 넣는
방식도 구현해 보장. (역시 막상 해보면 머얌 쉽넹 할 정도로 쉽당!)
심플하게 아래와 같은 메뉴 구조도(json형식)를 매개변수로 받는 다고 가정!
const menus = [
{
main: "블랙핑크",
subs: ["로제", "제니", "리사","지수"],
fgColor:"yellow",
bgColor:"black"
},
{
main: "IVE",
subs: ["안유진", "가을", "레이", "장원영","리즈","이서"],
fgColor:"white",
bgColor:"darkgreen"
},
{
main: "에스파",
subs: ["카리나", "지젤", "윈터", "닝닝"],
fgColor:"yellow",
bgColor:"purple"
},
{
main: "레드벨벳",
subs: ["아이린", "슬기", "웬디", "조이","예리"],
fgColor:"white",
bgColor:"red"
},
];
대략 아래와 흐름이 비스무리한 소스가 만들어 질 것이당.
(오늘따라 생각이 튀어나오지 않는다면, 그냥 복사/붙여넣기로 흐름만 따라가보자)
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>사이드바 메뉴 참공</title>
<style>
#menuWrapper {
width: 200px;
text-align: center;
border: 5px solid pink;
display: none;
}
.hide {
display: none;
}
.show {
display: block;
color: white;
font-weight: bolder;
}
.mmain {
cursor: pointer;
}
#menuTemp {
display: none;
}
.menu {
margin-bottom: 10px;
font-weight: bolder;
}
.tleft {
text-align: left;
cursor: pointer;
}
.line {
margin-top: 5px;
width:210px;
height:5px;
background-color: blueviolet;
}
</style>
</head>
<body>
<button onclick="fMakeMenu()">한번에 메뉴구성 눌렁</button>
<div class="line"></div>
<div id="menuWrapper">
<!-- 복사해서 쓸 html 템플릿, 요따구로 쓰면 꽤나 편함-->
<div id="menuTemp" class="menu">
<div class="mmain" onclick="fsubClick(this)">메뉴이름</div>
<div class="msub hide">
<ul>
<li>서브메뉴1</li>
<li>서브메뉴2</li>
<li>서브메뉴3</li>
<li>서브메뉴4</li>
</ul>
</div>
</div>
</div>
<script>
// 기본 틀
const menuWrapper = document.querySelector("#menuWrapper");
const menuTemp = document.querySelector("#menuTemp");
let curMenuNum = 0;
function fRanColor() {
return `rgb(
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)}
)`;
}
// 처음 클릭하거나, 같은 메뉴 클릭
function fSelfToggle(eDiv) {
curMenuNum = eDiv.parentElement.id.split("-")[1];
let subDiv = eDiv.nextElementSibling; // eDiv.parentElement.children[1]
let curState = subDiv.classList.contains("hide");
if (curState) {
subDiv.classList.remove("hide");
subDiv.classList.add("show");
subDiv.style.backgroundColor = fRanColor();
return;
}
subDiv.classList.remove("show");
subDiv.classList.add("hide");
}
// 다른 메뉴 클릭
function fDiffClick(eDiv) {
let subDiv = menuWrapper.querySelector(`#menu-${curMenuNum}`)
.children[1];
subDiv.classList.remove("show");
subDiv.classList.add("hide");
subDiv = eDiv.nextElementSibling; // eDiv.parentElement.children[1]
curMenuNum = eDiv.parentElement.id.split("-")[1];
subDiv.classList.remove("hide");
subDiv.classList.add("show");
subDiv.style.backgroundColor = fRanColor();
}
function fsubClick(eDiv) {
if (!curMenuNum || curMenuNum == eDiv.parentElement.id.split("-")[1]) {
fSelfToggle(eDiv);
} else {
fDiffClick(eDiv);
}
}
const fSub = (msub) => {
alert(`${msub.innerHTML}을 누르셨어용!`);
};
let i = 1;
const fAddMenus = (menus) => {
menus.forEach((menu) => {
let tempMenu = menuTemp.cloneNode(true);
tempMenu.id = `menu-${i}`;
tempMenu.children[0].textContent = menu.main;
let submenuStr = "<ul>";
menu.subs.forEach((subMenu) => {
submenuStr += `<li class="tleft" onclick="fSub(this)"
style="color:${menu.fgColor};background-color:${menu.bgColor}"
>${subMenu}</li>`;
});
submenuStr += "</ul>";
console.log("체킁킁:", tempMenu.children[1]);
tempMenu.children[1].innerHTML = submenuStr;
menuWrapper.appendChild(tempMenu);
tempMenu.style.display = "block";
i++;
});
console.log("체킁:", menus);
};
// 한번에 메뉴 정의!
const menus = [
{
main: "블랙핑크",
subs: ["로제", "제니", "리사","지수"],
fgColor:"yellow",
bgColor:"black"
},
{
main: "IVE",
subs: ["안유진", "가을", "레이", "장원영","리즈","이서"],
fgColor:"white",
bgColor:"darkgreen"
},
{
main: "에스파",
subs: ["카리나", "지젤", "윈터", "닝닝"],
fgColor:"yellow",
bgColor:"purple"
},
{
main: "레드벨벳",
subs: ["아이린", "슬기", "웬디", "조이","예리"],
fgColor:"white",
bgColor:"red"
},
];
function fMakeMenu(){
fAddMenus(menus);
menuWrapper.style.display="block";
}
</script>
</body>
</html>
난 아래와 같은 결과를 얻었당. (더 잼나고 이쁘겡 추가 수정은 본인 몫이당)
있어보이지 않아서 쪼금은 실망이지만, CSS를 더 하고 싶진 않당.~~
진실의 양면성 진실은
맘 가운데 큰 길을 만든다.
진실이 진실일 수도
진실이 진실이 아닐수도
진실이었다가, 진실이 아닐수도
그 역도 진실일 수도 아닐수도
결국 진실이 아닌게 진실일수도.......
이때 그 누군가 나타나 이건 진실이고,
저건 거짓이야라고 정해준당.
그냥 넘 고맙당.
대신 그 누군가는 Off The Record여야 한당.
그 누군가는 끝내 진실이 된당.
https://www.youtube.com/watch?v=Kn0NJzKAPLE
엑셀(Excel) 파일 다루는 SheetJS (0) | 2024.08.01 |
---|---|
CKEditor5 임시샘플 (2) | 2024.06.18 |
재미로 맹글어보는 오른쪽 슬라이딩 메늉 (0) | 2024.05.30 |
IntersectionAPI 오디 한번 싸용해 보올깡 (0) | 2024.04.16 |
clipboard API 사용 복사/붙여넣기 (0) | 2024.04.16 |