작성
·
241
0
3개의 문 현재의 순서값에 클래스가 붙는걸 활용해서
텝 메뉴를 만들고자 합니다.
순서값을 .box에 어떻게 전달해야 할까요?
jquery에서는 간단히 this.index()로 알아냈는데 javascript로는 어렵네요. 팁을 알려주시면 감사하겠습니다.
<div id="wrap">
<div class="content">
<ul class="menu">
<li ><a href="#" class="btn"> 0menu</a></li>
<li><a href="#" class="btn"> 1menu</a></li>
<li><a href="#" class="btn"> 2menu</a></li>
<li><a href="#" class="btn"> 3menu</a></li>
</ul>
<ul class="box">
<li class="inner b01 Active">content01</li>
<li class="inner b02">content02</li>
<li class="inner b03">content03</li>
<li class="inner b04">content04</li>
</ul>
</div>
</div>
<script>
(function(){
const menuList = document.querySelector('.menu');
let currentItem;
const content=document.querySelector('.box');
function handler(e){
const targetElem = e.target;
// console.log(targetElem);
if(currentItem){
currentItem.classList.remove('On');
}
if(targetElem.classList.contains('btn')){
targetElem.parentNode.classList.add('On');
currentItem= targetElem.parentNode;
}
}
menuList.addEventListener('click',handler);
})()
</script>
답변 5
1
1
childNodes는 텍스트노드들까지 모두 포함하고 있어서 컨트롤하기가 번거롭기때문에, 관리할 객체들을 따로 querySelectorAll로 선택해두고 사용하시는게 좋습니다. (에러는 텍스트노드의 경우는 classList 속성을 갖고있지 않기 때문에 발생한 것이고요)
작성하신 코드를 최대한 살려서 동작하도록 바꿔봤습니다~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=!, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style-type: none;
}
#wrap {
width: 100vw;
height: 100vh;
background-color: #eee;
display: flex;
align-items: center;
justify-content: center;
}
.content {
width: 30vw;
height: 30vw;
border: 1px solid #000;
}
.menu {
display: flex;
}
.menu li {
width: 25%;
text-align: center;
border-right: 1px solid #fff;
height: 25px;
}
.menu li a {
display: block;
color: #fff;
background-color: rgb(109, 198, 240);
height: 25px;
text-decoration: none;
}
.menu li.On a {
background-color: #000;
}
.menu li:last-child {
border-right: none;
}
.box {
width: 100%;
height: calc(100% - 25px);
position: relative;
}
.box .inner {
position: absolute;
width: 100%;
height: 100%;
font-size: 5vw;
justify-content: center;
display: flex;
align-items: center;
opacity: 0;
}
.box .inner.Active {
opacity: 1;
}
.box .inner.b01 {
background-color: rgb(113, 156, 236);
}
.box .inner.b02 {
background-color: rgb(236, 113, 195);
}
.box .inner.b03 {
background-color: rgb(236, 199, 113);
}
.box .inner.b04 {
background-color: rgb(236, 172, 113);
}
</style>
</head>
<body>
<div id="wrap">
<div class="content">
<ul class="menu">
<li class="On"><a href="#" class="btn"> 0menu</a></li>
<li><a href="#" class="btn"> 1menu</a></li>
<li><a href="#" class="btn"> 2menu</a></li>
<li><a href="#" class="btn"> 3menu</a></li>
</ul>
<ul class="box">
<li class="inner b01 Active" data-index="0">content01</li>
<li class="inner b02" data-index="1">content02</li>
<li class="inner b03" data-index="2">content03</li>
<li class="inner b04" data-index="3">content04</li>
</ul>
</div>
</div>
<script>
(function () {
const menuList = document.querySelector(".menu");
const content = document.querySelector(".box");
const inner = content.querySelectorAll('.inner');
let currentItem = menuList.querySelector('.On');
let currentContent = content.querySelector('.Active');
function handler(e) {
const targetElem = e.target;
// console.log(targetElem);
if (currentItem) {
currentItem.classList.remove("On");
currentContent.classList.remove("Active");
}
if (targetElem.classList.contains("btn")) {
targetElem.parentNode.classList.add("On");
inner[targetElem.dataset.index].classList.add("Active");
currentItem = targetElem.parentNode;
currentContent = inner[targetElem.dataset.index];
console.log(currentContent);
}
}
menuList.addEventListener("click", handler);
// data-index 추가
menuList.querySelectorAll(".btn").forEach(function (item, i) {
item.dataset.index = i;
console.log(i);
// if (content.childNodes.classList.contains("inner")) {
// content.childNodes.dataset.index[i].classList.add("Active");
// }
});
})();
</script>
</body>
</html>
0
0
0
dataset 객체(data- 속성)을 이용하시면 쉽습니다.
아래와 같은 형태로 쓸 수 있는 표준 사용자정의 속성이라고 생각하시면 됩니다~
여기서 myname 부분은 직접 이름을 지으시면 됩니다.
<span data-myname="100"></span>
이렇게 하면 해당 span 객체에는
span객체.dataset { myname: 100 }
이런 속성이 자동으로 추가됩니다.
작성하신 코드에 data-index를 0부터 차례로 넣어주고, 클릭했을 때 콘솔 로그에 출력해보는 코드를 추가해 봤습니다.
html에 직접 넣으셔도 되고, 아래처럼 스크립트로(forEach) 넣어주셔도 되고요.
span객체.getAttribute("data-index")으로 이용하셔도 되고,
span객체.dataset.index로 접근하셔도 됩니다.
(function () {
const menuList = document.querySelector(".menu");
let currentItem;
const content = document.querySelector(".box");
function handler(e) {
const targetElem = e.target;
// console.log(targetElem);
if (currentItem) {
currentItem.classList.remove("On");
}
if (targetElem.classList.contains("btn")) {
targetElem.parentNode.classList.add("On");
currentItem = targetElem.parentNode;
// data-index 출력
console.log(targetElem.dataset.index);
}
}
menuList.addEventListener("click", handler);
// data-index 추가
menuList.querySelectorAll(".btn").forEach(function (item, i) {
item.dataset.index = i;
});
})();