• 카테고리

    질문 & 답변
  • 세부 분야

    웹 개발

  • 해결 여부

    미해결

3개의 문에서 질문드려요

20.09.28 11:44 작성 조회수 153

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

LEETY님의 프로필

LEETY

질문자

2020.09.28

감사합니다:) 또 배우고 가네요~ 추석 잘 보내세요!

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

네 JOON님도 추석 잘 보내세요^^

0

LEETY님의 프로필

LEETY

질문자

2020.09.28

<!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(109198240);
            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(113156236);
        }
        .box .inner.b02{
            background-color:rgb(236113195);
        }
        .box .inner.b03{
            background-color:rgb(236199113);
        }
        .box .inner.b04{
            background-color:rgb(236172113);
        }
    </style>
</head>
<body>
    <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" 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');

            let currentItem;
            const content=document.querySelector('.box');
            const inner = content.childNodes;
            console.log(inner);

            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);

            // 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>
이렇게 쓰니 에러가 뜨네요~ ㅜㅜ 자식요소의 dataset중 index가 i 인 아이한테 클래스 붙여라라고 생각한건데 잘못된 점이 무었일까요

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;
        });
      })();