2 글 보임 - 1 에서 2 까지 (총 2 중에서)
-
글쓴이글
-
2024년 4월 24일 16:57 #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 기능이 요소 선택자 문제인지 적용되는 요소의 순서가 하나씩 밀리게 되는데 어떻게 해결해야 하는지 여쭙고 싶습니다.
2024년 4월 24일 19:30 #121233
codingapple키 마스터드래그하거나 그러면 이벤트리스너 부착하는게 또 실행되는지 아니면 기존 상품목록이 지워지는지 확인해봅시다
-
글쓴이글
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
- 답변은 로그인 후 가능합니다.