3개의 문에서 질문드려요
317
작성한 질문수 3
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
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
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;
});
})();
왼쪽/오른쪽 동작시 딜레이 문제
0
93
1
변수 범위 관련 질문
0
106
1
perspective 문의
0
100
1
생성자 함수를 클래스 함수로 변경 하고 this 오류 관련
0
150
1
스크롤이 중간 위치에 있을 때 창의 크기를 변환하면 생기는 문제
0
127
1
animation이벤트 질문이요!
0
71
1
resize handler에서 질문이 있습니다.
0
110
1
카드 뒤집힐 때 F가 보인 이유
0
149
1
3d 뒤집기 추가효과
0
217
1
전진! 3D 스크롤 21 강의 질문
1
171
1
eventlistener 질문
0
149
1
zMove 를 1000으로 설정하는 이유에 대하여.
0
168
1
[정보-23강] ES6 class 문법으로 공부하시는 분들!! 화살표 함수로도 시도해보셔요!
1
191
1
동적으로 html 생성 후 이벤트 위임 질문 있습니다.
0
265
1
rotateY()에서 deg에 따른 차이
0
197
1
코드 작성 순서
0
275
1
이미지가 없는데 첨부파일을 다운 받는 방법이 있나요??
1
394
1
'이벤트 위임 보강 영상'에 있는 예제 html이 안 보입니다
0
265
2
섹션5 자바스크립트 이벤트 다루기 질문
1
243
1
[#전진! 3D 스크롤 11] mousePos 공식 질문 있습니다!
0
423
2
css 는 직접 작성을 해야하는걸까용?
0
326
1
translateZ 에 px 이 아닌 vw 로 값을 주신 이유가 있을가요?
0
360
2
house 부분에도 width , height 부분을 꽉 차게 주신 부분이 제가 이해한게 맞는지 궁금합니다.
0
305
2
left:-400vw 가 아닌 translateZ(100vw); 을 입력하신 이유가 궁금합니다.
0
306
2





