이 화면에서 JS로 만든 기능은 총 3가지 (배너 슬라이드, 네비게이션 메뉴 hover, 드롭다운 박스)

 

 

   < 배너 슬라이드 >   


let heroL = document.querySelector('#heroLeft')
let heroR = document.querySelector('#heroRight')
console.log(heroL, heroR)
//배너에 배치되어 있는 버튼을 가져온다.

let heroS = document.querySelectorAll('.hero_slider')
//움직일 배너 부분을 가져온다.

let heroCount = 0;
//기능 작동에 필요한 변수를 초기화 한다, 지역변수로 할당하면 안된다. (전역에서 변해야 하는 값이므로)

heroL.addEventListener('click', heroLeft)
heroR.addEventListener('click', heroRight)
//가져온 버튼에 이벤트를 할당한다. 클릭하면 작성한 기능이 실행된다.

function heroLeft(){
  heroCount--;
  //왼쪽 버튼을 누르면 1씩 감소된다.

  //변수의 값이 음수가 되는 경우 배너의 인덱스 마지막 부분으로 이동할 수 있도록 한다.
  //배열의 길이는 1부터 시작하지만 인덱스 번호는 0부터 시작하므로 -1을 해주어야 실제 길이가 맞다.
  if(heroCount<0){
    heroCount = heroS.length-1
  }
  heroL.style.backgroundColor = "#fda417"
  heroL.style.color = "white"
  heroR.style.backgroundColor = "white"
  heroR.style.color = "#07092f"
  //누르면 버튼의 색이 교차로 바뀌는 속성을 지정해주었다.

  heroShow()
  //실제 배너가 움직이는 기능을 포함시켜주어야 화면이 움직인다.
}

function heroRight(){
  heroCount++;
  //오른쪽 버튼을 누르면 1씩 증가한다.

  //변수의 값이 배너의 인덱스 수 보다 많아지게 되면 다시 초기값(0)으로 돌린다.
  if(heroCount>=heroS.length){
    heroCount = 0
  }
  heroR.style.backgroundColor = "#fda417"
  heroR.style.color = "white"
  heroL.style.backgroundColor = "white"
  heroL.style.color = "#07092f"

  heroShow()
}

//실제 배너가 움직이는 효과를 내어 줄 기능이다.
function heroShow(){
  console.log('배너')
  heroS.forEach(function(array){
    array.style.transform = `translateX(-${heroCount*100}%)`
  })
}

 

 

   <네비게이션 메뉴 마우스 over/out 기능 >


let navHover = document.querySelectorAll('#nav_ul > li > a')
//네비게이션 메뉴를 가져오기, CSS 선택자로 작성해도 이상없다.


navHover.forEach(function(array){
  array.addEventListener("mouseover", navColor1)
  array.addEventListener("mouseout", navColor2)
  //이벤트는 같은 항목에 여러번 할당할 수 있다.
})
//각 메뉴들에게 over와 out 이벤트를 지정하고 기능을 연결하기


function navColor1(){
  console.log('오버')
  this.style.color = "#fda417"
  // this는 해당 이벤트가 발생한 요소를 가져오게 되는데, 그렇게 가져온 요소의 속성을 변경할 수 있다.

}

function navColor2(){
  console.log('아웃')
  this.style.color = "white"
}

 

 

   <드롭다운 박스>


let testimonial = document.querySelector('#nav_test')
let testBox = document.querySelector('#nav_test_box')
let testCount = 0;
//드롭다운 박스를 클릭을 할 때마다 나타났다 사라지게 만드는 기능이다
//필요한 요소를 HTML에서 가져오고 전역변수로 필요한 카운트를 선언 및 초기화 해둔다.

testimonial.addEventListener('click', navTestbox)
//클릭 이벤트를 두번 주게되면 나타났다, 사라졌다를 순차적으로 반복하기 때문에 이번 기능에서는 그렇게 하면 안된다.

function navTestbox(){
  testCount++;
  //기본적으로 클릭 할 때마다 변수의 값이 1씩 증가하도록 한다.

  //변수의 값을 2로 나누었을 때의 나머지가 0인 경우는 짝수라는 뜻이므로, 짝수일 때 드롭박스가 보이지 않게 한다.
  //반대로 나누었을 때 나머지가 있다면 홀수라는 뜻이므로, 홀수일 때 드롭박스가 나타나게 만든다.
  if(testCount%2==0){
    testBox.style.opacity = "0"
    testBox.style.top = "50px"
  } else{
    testBox.style.opacity = "1"
    testBox.style.top = "25px"
    //투명도와 위치를 조절하여 나타나게 만든다.
  }
}


   이 화면에서 쓰인 JS기능은 탭의 색상을 바꾸는 한가지

   하단의 슬라이드는 CSS애니메이션 효과를 사용해 자동으로 넘어가게끔 만들었으므로 오랜만에 기록해보겠다.

 


let proTab = document.querySelectorAll('.pro_ul > li > a')
//탭의 버튼들을 가져와준다.

proTab.forEach(function(array){
  array.addEventListener('click', projectTap)
})
//각 탭에 이벤트를 할당한다.

function projectTap(){
  proReset()
  //색상 초기화 기능을 만들어 넣었지만 그냥 해당 기능의 구문을 여기에 작성해도 정상적으로 작동한다.
  //아래에서 색상을 바꾼 탭들이 다음으로 넘어갈 때마다 원래 색으로 돌아오게 하는 기능이다.
  //위에서부터 순차적으로 기능이 실행되기 때문에 초기화를 하고 그 이후 if문에 맞는 탭의 색상이 변하게 된다.

  let proID = this.id.charAt(this.id.length-1)
  //클릭한 탭의 속성에서 ID값의 맨 끝자리를 가져와 배열의 숫자와 비교해 같을 경우 색상을 변경하도록 만들었다.
  //탭의 아이디 뒤에는 0부터 5까지의 숫자를 입력해두었기 때문에 비교가 가능하다.

  for(let i=0; i<proTab.length; i++){
    //1씩 증가하는 i의 값이 가져온 ID의 값과 동일하면 색상이 바뀐다.
    if(proID == i){
      proTab[i].style.backgroundColor = "#fda417"
    }
  }
}

//다음 탭으로 넘어가면 원래의 색상으로 돌아오는 기능
function proReset(){
  proTab.forEach(function(array){
    array.style.backgroundColor = "white"
  })
}

 

 

See the Pen Untitled by IT배움터 (@gfifvcbf-the-typescripter) on CodePen.


.pro_slider{
  width: 100%;
  display: inline-block;
  animation: proSlider 4.5s ease-in-out infinite;
  //keyframes로 만든 애니메이션을 지정하기
  //총 과정을 4.5초 동안 진행되게 만들고 애니메이션의 속도를 지정한 후 반복여부를 결정하면 설정은 끝
}

@keyframes proSlider{
  0% {
    transform: translateX(0%);
    //제자리인 상태
  }

  40% {
    transform: translateX(-100%);
    //-100%만큼 이동한 상태
  }

  100%{
    transform: translateX(-100%);
    //그 상태로 일시정지
  }
}

 

 

이미지 주소로만 변경했던 야매(?)슬라이드를 좀 더 부드러운 동작이 담긴 버전으로 구현해보자.

 


let leftB = document.querySelector('#left')
let rightB = document.querySelector('#right')
leftB.addEventListener("click", leftSlide)
rightB.addEventListener("click", rightSlide)

let sliderLi = document.querySelectorAll('.slider_li')
let count = 0;

function leftSlide(){
  count--;
  //왼쪽 버튼을 누를 때마다 count 변수에 담긴 값에서 -1
  if(count < 0){
    count = (sliderLi.length-1);
    //count가 0보다 작은 숫자가 되면 sliderLi의 마지막 인덱스 번호가 들어가게끔 if문 설정

  }
  show() //아래에 작성한 기능, 화면을 넘겨주는 이벤트  
}

function rightSlide(){
  count++;
  //오른쪽 버튼을 누를 때마다 count 변수에 담긴 값에서 +1

  if(count >= sliderLi.length){
    count = 0;
    //count가 sliderLi 배열의 길이보다 크거나 같은 숫자가 되면 count값을 초기로 되돌려 놓음

  }
  show()
}

function show(){
  sliderLi.forEach(function(array){
    array.style.transform = `translateX(-${count*100}%)`
    //for문 혹은 forEach로 배열의 각 요소에게 원하는 CSS속성을 입력함
  })
}

 


 

   이번에는 슬라이드에 이어 탭 형식도 js로 작성해보자. input태그를 통한 radio 방식으로는 그렇게 어렵지 않았는데 js는 HTML에서 읽어온 뒤, 기능을 만들어 적용해야 한다는 점이 아직은 익숙하지 않은 것 같아 상세하게 남겨보도록 하겠다.

 


<section>

    <ul id="tap_list"> //상단의 탭이 될 부분
      <li class="fashion_tab" id="ftap1">Best Sellers</li>
      <li class="fashion_tab" id="ftap2">New Arrivals</li>
      <li class="fashion_tab" id="ftap3">Hot sales</li>
    </ul>
    <div id="pro_list"> //하단의 컨텐츠가 나타나는 부분
      <div class="pro_box1 pro_box2" id="pro1"> ... </div>
      <div class="pro_box1 pro_box3" id="pro2"> ... </div>
      <div class="pro_box1 pro_box2" id="pro3"> ... </div>
      <div class="pro_box1 pro_box3" id="pro4"> ... </div>
      <div class="pro_box1 pro_box2" id="pro5"> ... </div>
      <div class="pro_box1 pro_box3" id="pro6"> ... </div>
      <div class="pro_box1 pro_box2" id="pro7"> ... </div>
      <div class="pro_box1 pro_box3" id="pro8"> ... </div> //최대한 숫자를 활용하는 편이 편하다.
    </div>

  </section>

 


let tabBtu = document.querySelectorAll('.fashion_tap')
//탭 버튼이 될 li들을 불러와서 변수에 담는다.

consol.log 확인 결과
NodeList(3) [li#ftap1.fashion_tap, li#ftap2.fashion_tap, li#ftap3.fashion_tap]
0: li#ftap1.fashion_tap
1: li#ftap2.fashion_tap.active
2: li#ftap3.fashion_tap


for(let i=0; i<tabBtu.length; i++){
  tabBtu[i].addEventListener('click', tabSelected)
}
//배열의 각 요소에 반복문을 활용하여 각 인덱스에 이벤트를 할당해준다.


function tabSelected(){
  let tabID = 'pro_box' + this.id.charAt(this.id.length-1)
  //ftap(숫자) 부분에서 마지막 숫자 부분만 들고와 테이블의 id와 똑같이 만들기

  console.log 확인 결과 //각 탭을 누를 때마다 반환되는 값이다.
  pro_box1
  pro_box2
  pro_box3


  tabActive(this) //클릭한 값을 가져와서 tap 매개변수에 삽입하여 작동하게 만듦.
  showTable(tabID) //지역변수로 선언된 tabID를 해당 기능의 매개변수에 삽입
}


function tabActive(tab){
  for(let i=0; i<tabBtu.length; i++){
    tabBtu[i].className = "fashion_tab";
    //다시 원래 값으로 돌려놓는 반복문
    //아래에서 active 값을 준 것을 다시 초기화 하기 위해서 필요하다.
    //먼저 선언된 기능이기 때문에 초기화가 먼저 돈 이후 active 추가하는 기능이 작동된다.

  }

  tab.className = "fashion_tab active"
  //active를 추가해 css속성을 주기 위함
  //해당 기능에서는 this로 값을 가져옴

}


function showTable(tabID){
  let proBox = document.querySelectorAll('.pro_box1')
  //탭이 변경 될 때마다 제품들이 나타났다 사라졌다 하기 위해 공통된 클래스 값을 가져와 변수에 저장

  for(let i=0; i<proBox.length; i++){
    proBox[i].style.display = "none"
  }

  let proTable = document.querySelectorAll("."+tabID)
  //단일이 아닌 여러개에 스타일을 줘야 하기 때문에 위와 마찬가지로 반복문을 통해 각 배열에 값을 지정해줘야한다.
  if(proTable){
    proTable.forEach(function(array){
      array.style.display = "block"
    })
   //선택된 클래스만 보이도록 none/block값을 지정하면 끝
  }
}


tabActive(tabBtu[0])
showTable('pro_box1')
//첫 화면에도 탭이 보일 수 있도록 초기값을 지정

 

   위 기능을 코드펜으로 작성하면 이렇게 된다.

 

See the Pen Untitled by IT배움터 (@gfifvcbf-the-typescripter) on CodePen.

 

   어려운 듯 알 듯 말 듯... 아직은 낯설지만 친해질 수 있기를...

+ Recent posts