• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 JavaScript, TS 게시판 강의 응용 중 JS질문입니다

강의 응용 중 JS질문입니다

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 글쓴이
  • #121220

    송승환
    참가자
    var header = document.querySelectorAll('.headerContent p')
    var clickcount = 0;
    var cart = [];
    var total = 0;
    var strr = 0;
    var totalSum = 0;
    var index;
    var slid = []
    var dragTarget;
    for (let i = 0; i < header.length; i++) {
        header[i].addEventListener('click', function () {
            for (let j = 0; j < header.length; j++) {
                header[j].classList.remove('headerContent_show');
            }
            this.classList.add('headerContent_show')
        })
    }
    document.querySelector('.searchBtn').addEventListener('click', function () {
        document.querySelector('.searchBar').classList.toggle('searchShow')
    })
    document.querySelector('.cartBtn').addEventListener('click', function (e) {
        document.querySelector('.cart').classList.add('cartShow')
    })
    document.querySelector('.cart').addEventListener('click', function (e) {
        if (e.target == document.querySelector('.cart')) {
            document.querySelector('.cart').classList.remove('cartShow')
        }
    })
    // 호버시 콘텐츠 보여주기 기능 구현해야함
    fetch('apple.json').then(function (data) {
        return data.json();
    })
        .then(function (product) {
            console.log(product);
            function addCart(q) {                    // addCart의 이름으로 add버튼을 눌렀을 때
                if (!cart.some(function (x) { return x.id === q })) {       // 만약 cart 어레이안에 누른 요소가 없다면 아래의 코드를 실행.  /  some()함수는 배열의 각 요소에 괄호안에 제공된 테스트 함수의 유무를 검사하고 존재시에는 true를, 존재하지 않을 경우 false를 반환합니다.
                    //없다면 cart에 추가                                     // (function(x) {return x.id === b})는 some이 사용된 cart배열의 요소를 인수로 x에 받아 x.id와 b의 동일성을 검사합니다. 동일시 true, 동일하지 않을시 false를 반환합니다.  
                    item = { id: q, count: 1, price: product.products[q].price }              // item 속성값에 object 자료형을 추가.
                    cart.push(item);                                        // cart array 자료형 안에 위의 코드형식의 item object 데이터를 추가, id는 인덱스 번호, count는 1, price는 fetch로 가져온 데이터 안의 price로 저장
                    var cartTemplat = document.createElement('div')         // cartTemplat의 변수에 만들어질 HTML 구조를 설정.  / vanila JS에서는 하나하나 지정해 줘야 정상 작동
                    cartTemplat.className = 'cartItem';
                    cartTemplat.setAttribute('data-id', q)
                    cartTemplat.innerHTML = `
                        < img src="${product.products[q].photo}" class="imgg">
                        <h4>${product.products[q].title}</h4>
                        <div class="count">Count : 1</div>
                        <h5>$${product.products[q].price}</h5>`
                    document.querySelector('.cartBox').appendChild(cartTemplat); // cartBox안에 cartTemplat을 자식요소로 추가
    
    
                    var lighter = document.createElement('div');                // lighter 변수에 HTML구조 지정
                    lighter.className = 'alertBar';
                    lighter.innerHTML = `${product.products[q].title} Add`
                    document.querySelector('.container').appendChild(lighter)   // container 안에 lighter을 자식요소로 추가
                    setTimeout(function () {                                    //setTimeout 함수로 lighter을 시간에 따른 스타일 변화를 지정 / lighter은 물건을 처음 cart에 추가했을때 작동하는 alert형식으로 3초 후에 opacity가 0이 되며 사라짐
                        lighter.style.opacity = '0';
                        lighter.addEventListener('transitionend', function () {  // lighter에 addEventListener을 사용해 transitionend를 확인한 후 작동합니다. transition이 끝나는 시점을 확인합니다.
                            this.remove();                                       // this는 lighter을 뜻하며 transition 이벤트가 끝나면 transitionend가 작동해 lighter DOM 요소를 완전히 제거합니다.
                        });
                    }, 3000);                                                    // 3초 후 작동을 지정합니다.
    
    
    
    
                } else {                                                        // 만약 cart를 some을 통해 검사했을때 이미 요소가 있어 true가 반환되었을 때 작동하는 코드입니다.
                    item.count++                                                // cart.some의 결과값이 true, 즉 이미 있다면 그 요소의 item 속성의 count를 1 증가시킵니다.
                    document.querySelectorAll('.cartItem').forEach(function (a, x) {    // cartItem의 수만큼 반복하며 a는 데이터, x는 인덱스를 저장합니다.
                        var setID = a.getAttribute('data-id');                  // setID에는 받아온 데이터 a의 data-id를 가져와 저장합니다.
                        if (setID === q.toString()) {                           // 만약 가져온 setID가 인덱스를 나타내는 매개변수인 b를 string으로 변경한것과 같다면 아래의 코드를 실행합니다.
                            document.querySelectorAll('.count')[x].innerHTML = `Count : ${item.count}`;  // if의 결과값이 true라면 count클래스를 가진 요소의 x번째 요소에 내용을 업데이트합니다.
                        }
                        var lighter = document.createElement('div');        // lighter 변수에 HTML의 구조를 지정합니다.
                        lighter.className = 'alertBar';
                        lighter.innerHTML = `${a.title} Add More! Count : ${item.count}`    // 상품명과 현재 연산된 item.count를 출력합니다.
                        document.querySelector('.container').appendChild(lighter)       // container에 자식 요소로 lighter을 추가합니다.
                        setTimeout(function () {                                            //상동
                            lighter.style.opacity = '0';
                            lighter.addEventListener('transitionend', function () {
                                this.remove();
                            });
                        }, 3000);
                    })
    
    
                }
            }
            product.products.forEach(function (a, b) {  //  a는 json의 데이터, b는 인덱스 번호
                // else 문 끝
                var templat = document.createElement('div');                                      // templat 안에 HTML 구조 추가
                templat.className = 'item'
                templat.draggable = true
                templat.innerHTML = `
                < img src="${a.photo}" class="imgg">
                <h4>${a.title}</h4>
                <div class="hide">
                    <h5>$${a.price}</h5>
                    <p>${a.info.replace(/\n/g, '<br>')}</p>
                </div>
                <button class="addTo"><i class="fa-solid fa-plus plus">Add</i></button>`
                document.querySelector('.mainContent').appendChild(templat);                       // mainContent 안에 자식 요소로 templat 추가
                document.querySelectorAll('.addTo')[b].addEventListener('click', function (e) {     // addTo 버튼 눌렀을 때 작동
                    let item = cart.find(function (item) { return item.id === b })                  // 뭔데 얘
                    addCart(b)                                                                       // addCart 함수 실행
    
    
                })
                document.querySelectorAll('.item')[b].addEventListener('dragstart', function (e) {  // item 요소 드래그 시작시 실행
                    document.querySelector('.miniCart').style.height = '120px';                     // miniCart 요소의 높이 변경
                    index = b                  // 위에서 지정한 data-id를 가져와 data 라는 이름으로 e.dataTransfer함수에 데이터를 set
                })
                document.querySelector('.miniCart').addEventListener('dragover', function (e) {
                    e.preventDefault();                                                             //기본 설정 삭제
                })
                document.querySelector('.miniCart').addEventListener('drop', function (e) {
                    e.preventDefault();                                                                 //기본 설정 삭제
                    document.querySelector('.miniCart').style.height = '0px';                        // miniCart 요소의 높이 변경
                    if (index == b) {
                        addCart(index);                                                                  // addCart함수 실행, 인자로 index 받음    /     이거 오류임 수정 필요
                    } else {
                    }
                })
           
    
    
            // 제품의 card 위에 마우스가 호버 되었을때 추가 정보를 보여주기 위한 효과  /  추가 정보는 apple.json데이터셋의 안에서 가져오기 때문에 fetch 안에 작성함
                document.querySelectorAll(`.item`)[b].addEventListener('mouseover', function () {
                    document.querySelectorAll('.hide')[b].classList.add('hideShow')
                    document.querySelectorAll('.imgg')[b].style.transform = 'scale(1.2)'
                })
                document.querySelectorAll('.item')[b].addEventListener('mouseout', function () {
                    document.querySelectorAll('.hide')[b].classList.remove('hideShow')
                    document.querySelectorAll('.imgg')[b].style.transform = `scale(1)`
                })
            })
            //searchbar 만들거임
            document.querySelector('.searchBar').addEventListener('input', function (e) {
                var vals = e.target.value.toLowerCase();   // toLowerCase는 소문자로 변경한다는 문법
                var rods = product.products.filter(function (a) { return a.title.toLowerCase().startsWith(vals) })
                document.querySelector('.mainContent').innerHTML = ''
                rods.forEach(function (a) {
                    var templat = document.createElement('div');                                      // templat 안에 HTML 구조 추가
                    templat.className = 'item'
                    templat.draggable = true
                    templat.innerHTML = `
                        < img src="${a.photo}" class="imgg">
                        <h4>${a.title}</h4>
                        <div class="hide">
                        <h5>$${a.price}</h5>
                        </div>
                        <button class="addTo"><i class="fa-solid fa-plus plus">Add</i></button>`
                    document.querySelector('.mainContent').appendChild(templat);
                })
            })
    
    
        })
    
    
    // cart의 구매 버튼을 눌렀을 때 영수증 창을 출력하는 효과
    document.querySelector('.cart button').addEventListener('click', function () {
        document.querySelector('.cart').classList.remove('cartShow')
        document.querySelector('.black-bg').classList.add('black-bgShow')
        console.log(cart)
        cart.forEach(function (a) {                             // cart안의 데이터 수만큼 반복합니다. a를 인수로 지정합니다.
            if (!slid[a.id]) {                                  // 만약 slid의 안에 a.id가 없다면 아래의 코드를 실행합니다.
                slid[a.id] = a.price * a.count;                 // slid안에 a.id는 a.price와 a.count를 곱한 수를 저장합니다.
            }
        });
        totalSum = slid.reduce((acc, current) => {              //totalSum은 slid에 reduce함수를 사용합니다. reduce함수는 두개의 인자를 받으며 하나의 결과값을 출력합니다. 첫번째는 리듀서 함수이며 배열의 요소를 하나하나 받음, 두번째는 누적값의 초기값이다. 
            return acc + (current ? current : 0);               // undefined 값을 처리하기 위해 조건부 사용  /  return을 통해 오른쪽 코드의 결과값을 반환한다, 오른쪽 코드는 acc(리듀서 함수) + current(초기값) ? current : 0이며 식 중 current식의 의미는 current값이 undefined , null , false와 같은 falsy한 값이라면 0을 반환한다는 의미이며 그 외의 값은 그대로 사용한다는 의미이다.
        }, 0);                                              //reduce 함수의 초기값을 0으로 설정합니다.
        document.querySelector('.totalBox h5').innerHTML = `Total : $${totalSum}`  // totalBox 의 h5 안의 내용에 totalSum을 추가합니다. / 총합 계산
        console.log(totalSum)
    });
    // 영수증 모달 이외의 부분을 누르면 영수증 모달을 없애는 효과
    document.querySelector('.black-bg').addEventListener('click', function (e) {
        if (e.target == document.querySelectorAll('.recipt input')[0]) {
            return
        } else if (e.target == document.querySelectorAll('.recipt input')[1]) {
            return
        } else if (e.target == document.querySelectorAll('.recipt input')[2]) {
            return
        } else if (e.target == document.querySelectorAll('.recipt input')[3]) {
            return
        } else if (e.target == document.querySelectorAll('.recipt input')[4]) {
            return
        } else if (e.target == document.querySelector('.recipt')) {
            return
        } else {
            document.querySelector('.black-bg').classList.remove('black-bgShow')
        }
    })
    
    
    // scroll에 따른 video 재생 효과
    var vdo = document.querySelector('.vdo')
    window.addEventListener('scroll', function () {
        console.log(window.scrollY)
        var windowHigh = window.innerHeight;
        var wvl = windowHigh + window.scrollY;
        console.log(wvl)
        if (wvl > 2100 || wvl <= 1200) {
            vdo.pause();
        } else {
            vdo.play();
        }
    })
    
    
    var productApple = [{title : 'Store', photo : '#'}, {title : 'Mac', photo : '/img/MacBook-Air-Cambodia-removebg-preview.png'}, {title : 'iPad', photo : '/img/cameras_lidar_1__bisiznolk9w2_large_2x.jpg'}]
    productApple.forEach(function (a, i) {
        document.querySelectorAll('.headerContent p')[i].addEventListener('click', function (e) {
            document.querySelector('.infoL').classList.add('infoL_show')
            document.querySelector('.infoContent').classList.add('infoContent_show')
            var name = e.target.innerHTML;
            var templat2 = document.createElement('div')
            templat2.className = 'information'
            templat2.innerHTML = `
            <h4>${a.title}</h4>
            <div class="rotate">
                < img src="${a.photo}">
                <video autoplay="autoplay" loop="loop">
                    <source src="/img/apple_info.mp4">
                </video>
            </div>`
            document.querySelector('.infoContent').innerHTML = ''
            switch(i){
                case 0 :
                    break
                case 1 :
                    document.querySelector('.infoContent').appendChild(templat2);
                    break
                case 2 :
                    templat2.innerHTML = `<h4>${a.title}</h4>
                    <div class="rotate">
                        < img src="${a.photo}" style="width : 80%; margin : auto; margin-top : 30px">
                    </div>`
                    document.querySelector('.infoContent').appendChild(templat2)
                    break
            }
           
        })
        document.querySelector('.infoL').addEventListener('click', function (e) {
            if (e.target !== document.querySelector('.infoContent') && e.target == document.querySelector('.infoL')) {
                document.querySelector('.infoL').classList.remove('infoL_show')
                document.querySelector('.infoContent').classList.remove('infoContent_show')
            }
        })
        // console.log(name)
    });
    전체 코드입니다.
    
    
    이중 js로 구현한 drag&drop 기능을 실행하면 잘 작동되던 mouseover, mouseout 기능이 요소 선택자 문제인지 적용되는 요소의 순서가 하나씩 밀리게 되는데 어떻게 해결해야 하는지 여쭙고 싶습니다.
    제목 없는 동영상 - Clipchamp로 제작 (1)
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
     
    #121233

    codingapple
    키 마스터
    드래그하거나 그러면 이벤트리스너 부착하는게 또 실행되는지 아니면 기존 상품목록이 지워지는지 확인해봅시다
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠