본문 바로가기
JavaScript

[Javascript] tabs

by teamnova 2024. 5. 20.
728x90

 

오늘은 자바스크립트로 tab을 이동하는 예제를 가져왔습니다. 

 

 

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Tabs</title>

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <section class="section">
      <div class="title">
        <h2>about</h2>
        <p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Earum,
          aperiam!
        </p>
      </div>

      <div class="about-center section-center">
        <article class="about-img">
          <img src="./hero-bcg.jpeg" alt="" />
        </article>
        <article class="about">
          <!-- btn container -->
          <div class="btn-container">
            <button class="tab-btn active" data-id="history">history</button>
            <button class="tab-btn" data-id="vision">vision</button>
            <button class="tab-btn" data-id="goals">goals</button>
          </div>
          <div class="about-content">
            <!-- single item -->
            <div class="content active" id="history">
              <h4>history</h4>
              <p>
                I'm baby wolf pickled schlitz try-hard normcore marfa man bun
                mumblecore vice pop-up XOXO lomo kombucha glossier bicycle
                rights. Umami kinfolk salvia jean shorts offal venmo. Knausgaard
                tilde try-hard, woke fixie banjo man bun. Small batch tumeric
                mustache tbh wayfarers 8-bit shaman chartreuse tacos. Viral
                direct trade hoodie ugh chambray, craft beer pork belly flannel
                tacos single-origin coffee art party migas plaid pop-up.
              </p>
            </div>
            <!-- end of single item -->
            <!-- single item -->
            <div class="content" id="vision">
              <h4>vision</h4>
              <p>
                Man bun PBR&B keytar copper mug prism, hell of helvetica. Synth
                crucifix offal deep v hella biodiesel. Church-key listicle
                polaroid put a bird on it chillwave palo santo enamel pin,
                tattooed meggings franzen la croix cray. Retro yr aesthetic four
                loko tbh helvetica air plant, neutra palo santo tofu mumblecore.
                Hoodie bushwick pour-over jean shorts chartreuse shabby chic.
                Roof party hammock master cleanse pop-up truffaut, bicycle
                rights skateboard affogato readymade sustainable deep v
                live-edge schlitz narwhal.
              </p>
              <ul>
                <li>list item</li>
                <li>list item</li>
                <li>list item</li>
              </ul>
            </div>
            <!-- end of single item -->
            <!-- single item -->
            <div class="content" id="goals">
              <h4>goals</h4>
              <p>
                Chambray authentic truffaut, kickstarter brunch taxidermy vape
                heirloom four dollar toast raclette shoreditch church-key.
                Poutine etsy tote bag, cred fingerstache leggings cornhole
                everyday carry blog gastropub. Brunch biodiesel sartorial mlkshk
                swag, mixtape hashtag marfa readymade direct trade man braid
                cold-pressed roof party. Small batch adaptogen coloring book
                heirloom. Letterpress food truck hammock literally hell of wolf
                beard adaptogen everyday carry. Dreamcatcher pitchfork yuccie,
                banh mi salvia venmo photo booth quinoa chicharrones.
              </p>
            </div>
            <!-- end of single item -->
          </div>
        </article>
      </div>
    </section>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

styles.css

/*
=============== 
Fonts
===============
*/
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");

/*
=============== 
Variables
===============
*/

:root {
  /* dark shades of primary color*/
  --clr-primary-1: hsl(205, 86%, 17%);
  --clr-primary-2: hsl(205, 77%, 27%);
  --clr-primary-3: hsl(205, 72%, 37%);
  --clr-primary-4: hsl(205, 63%, 48%);
  /* primary/main color */
  --clr-primary-5: #49a6e9;
  /* lighter shades of primary color */
  --clr-primary-6: hsl(205, 89%, 70%);
  --clr-primary-7: hsl(205, 90%, 76%);
  --clr-primary-8: hsl(205, 86%, 81%);
  --clr-primary-9: hsl(205, 90%, 88%);
  --clr-primary-10: hsl(205, 100%, 96%);
  /* darkest grey - used for headings */
  --clr-grey-1: hsl(209, 61%, 16%);
  --clr-grey-2: hsl(211, 39%, 23%);
  --clr-grey-3: hsl(209, 34%, 30%);
  --clr-grey-4: hsl(209, 28%, 39%);
  /* grey used for paragraphs */
  --clr-grey-5: hsl(210, 22%, 49%);
  --clr-grey-6: hsl(209, 23%, 60%);
  --clr-grey-7: hsl(211, 27%, 70%);
  --clr-grey-8: hsl(210, 31%, 80%);
  --clr-grey-9: hsl(212, 33%, 89%);
  --clr-grey-10: hsl(210, 36%, 96%);
  --clr-white: #fff;
  --clr-red-dark: hsl(360, 67%, 44%);
  --clr-red-light: hsl(360, 71%, 66%);
  --clr-green-dark: hsl(125, 67%, 44%);
  --clr-green-light: hsl(125, 71%, 66%);
  --clr-black: #222;
  --ff-primary: "Roboto", sans-serif;
  --ff-secondary: "Open Sans", sans-serif;
  --transition: all 0.3s linear;
  --spacing: 0.25rem;
  --radius: 0.5rem;
  --light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  --dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  --max-width: 1170px;
  --fixed-width: 620px;
}
/*
=============== 
Global Styles
===============
*/

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: var(--ff-secondary);
  background: var(--clr-grey-10);
  color: var(--clr-grey-1);
  line-height: 1.5;
  font-size: 0.875rem;
}
ul {
  list-style-type: none;
}
a {
  text-decoration: none;
}
img:not(.logo) {
  width: 100%;
}
img {
  display: block;
}

h1,
h2,
h3,
h4 {
  letter-spacing: var(--spacing);
  text-transform: capitalize;
  line-height: 1.25;
  margin-bottom: 0.75rem;
  font-family: var(--ff-primary);
}
h1 {
  font-size: 3rem;
}
h2 {
  font-size: 2rem;
}
h3 {
  font-size: 1.25rem;
}
h4 {
  font-size: 0.875rem;
}
p {
  margin-bottom: 1.25rem;
  color: var(--clr-grey-5);
}
@media screen and (min-width: 800px) {
  h1 {
    font-size: 4rem;
  }
  h2 {
    font-size: 2.5rem;
  }
  h3 {
    font-size: 1.75rem;
  }
  h4 {
    font-size: 1rem;
  }
  body {
    font-size: 1rem;
  }
  h1,
  h2,
  h3,
  h4 {
    line-height: 1;
  }
}
/*  global classes */

.btn {
  text-transform: uppercase;
  background: transparent;
  color: var(--clr-black);
  padding: 0.375rem 0.75rem;
  letter-spacing: var(--spacing);
  display: inline-block;
  transition: var(--transition);
  font-size: 0.875rem;
  border: 2px solid var(--clr-black);
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  border-radius: var(--radius);
}
.btn:hover {
  color: var(--clr-white);
  background: var(--clr-black);
}
/* section */
.section {
  padding: 5rem 0;
}

.section-center {
  width: 90vw;
  margin: 0 auto;
  max-width: 1170px;
}
@media screen and (min-width: 992px) {
  .section-center {
    width: 95vw;
  }
}
main {
  min-height: 100vh;
  display: grid;
  place-items: center;
}
/*
=============== 
About
===============
*/
.title {
  text-align: center;
  margin-bottom: 4rem;
}
.title p {
  width: 80%;
  margin: 0 auto;
}

.about-img {
  margin-bottom: 2rem;
}
.about-img img {
  border-radius: var(--radius);
  object-fit: cover;
  height: 20rem;
}
@media screen and (min-width: 992px) {
  .about-img {
    margin-bottom: 0;
  }

  .about-center {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 2rem;
  }
}
.about {
  background: var(--clr-white);
  border-radius: var(--radius);
  display: grid;
  grid-template-rows: auto 1fr;
}
.btn-container {
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
.tab-btn:nth-child(1) {
  border-top-left-radius: var(--radius);
}
.tab-btn:nth-child(3) {
  border-top-right-radius: var(--radius);
}
.tab-btn {
  padding: 1rem 0;
  border: none;
  text-transform: capitalize;
  font-size: 1rem;
  display: block;
  background: var(--clr-grey-9);
  cursor: pointer;
  transition: var(--transition);
  letter-spacing: var(--spacing);
}
.tab-btn:hover:not(.active) {
  background: var(--clr-primary-10);
  color: var(--clr-primary-5);
}
.about-content {
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
  padding: 2rem 1.5rem;
}
/* hide content */
.content {
  display: none;
}
.tab-btn.active {
  background: var(--clr-white);
}
.content.active {
  display: block;
}

 

app.js

// 클래스 "about"을 가진 요소를 선택합니다.
const about = document.querySelector(".about");

// 클래스 "tab-btn"을 가진 모든 요소를 선택합니다.
const btns = document.querySelectorAll(".tab-btn");

// 클래스 "content"을 가진 모든 요소를 선택합니다.
const articles = document.querySelectorAll(".content");

// 'about' 요소에 클릭 이벤트 리스너를 추가합니다.
about.addEventListener("click", function (e) {
  // 클릭된 대상의 데이터셋에서 'id' 값을 가져옵니다.
  const id = e.target.dataset.id;
  
  // 'id' 값이 있을 경우 아래 로직을 수행합니다.
  if (id) {
    // 다른 버튼들에서 "active" 클래스를 제거합니다.
    btns.forEach(function (btn) {
      btn.classList.remove("active");
    });
    
    // 클릭된 버튼에 "active" 클래스를 추가합니다.
    e.target.classList.add("active");
    
    // 다른 아티클들에서 "active" 클래스를 제거합니다.
    articles.forEach(function (article) {
      article.classList.remove("active");
    });
    
    // 'id' 값과 일치하는 요소를 찾아 "active" 클래스를 추가합니다.
    const element = document.getElementById(id);
    element.classList.add("active");
  }
});

 

 

 

'JavaScript' 카테고리의 다른 글

[Javascript] 문단 동적생성  (0) 2024.06.01
[Javascript] count-down timer  (0) 2024.05.26
[Javascript] Scroll  (0) 2024.05.10
[Javascript] 식당 메뉴판 만들기  (0) 2024.05.04
[Javascript] 버튼 이동 시키기  (0) 2024.04.29