✅ classList
엘리먼트.classList.add('추가할 클래스명')
엘리먼트.classList.remove()
ex)
-html파일 내
<ul class="navbar" id="navbar"> .. </ul>
잠깐만!!다중클래스,다중선택자
//html
<li class = "navbar first"></li> => 클래스가 navbar, first 두개인거임!
<li class = "navbar second"></li>
<li class = "navbar third"></li>
//css
.navbar.first => 클래스가 navbar랑 first 두개 다갖고있는놈
.first, .second => 반점을 찍으면 클래스 first랑 second 인놈들 선택할게요
-css파일 내
.navbar{
background-color:black
}
.navbar.invisible{
display:none;
}
-js파일 내
const navbar = document.querySelector('.navbar')
navbar.classList.add('invisible') ➡️ html내 <ul class="navbar invisible" id="navbar">...</ul>
remove는 지우는것!
✅ dataset
const a = 엘리먼트.dataset.데이터셋이름
HTML내에서
<button class="category__btn" data-filter="front-end">
태그의 내의 속성에
data-filter="front"
data-chicken="chick"
data-chicken-delicious="gupnae" //여러 단어하고싶을때는 - 써서 적는 스네이크표기법
이런식으로 적고
JS내에서
const a = 엘리먼트.dataset.filter //"front" 문자열을 리턴하여 변수a에 담김
const a = 엘리먼트.dataset.chicken //"chick"문자열 리턴하여 변수a에 담김
const a = 엘리먼트.dataset.chickenDelicious //"gupnae" 문자열이 반환되는데 위에는 - 가 더 있으면 JS내에서는 -를 없애는대신
앞글자를 대문자로 쓰는 카멜표기법
✅ map
배열 이터레이터 같은 느낌
sectionIds=['#a','#b','#bc','#c','.cc']
const sections = sectionIds.map((id) => document.querySelector(id));
이렇게하면 돌아가면서 값을 받아서 처리한 후 처리된 값들을 배열로 반환해쥼
'use strict';
//엄격한 문법 모드를 사용하겠다(개발할때 나은 환경)
//변수를 제대로 선언하지 않으면 에러를 발생시킨다
//*스크롤에 따른 메뉴바 색상처리
const navbar = document.querySelector('#navbar');
//Document 객체는 웹 페이지 그 자체를 의미합니다.
//웹 페이지에 존재하는 HTML 요소에 접근하고자 할 때는 반드시 Document 객체부터 시작해야함
//쿼리셀렉터를 통해 엘리먼트를 가져온다
const navbarHeight = navbar.getBoundingClientRect().height;
//const nab사각형의 높이를 가져와라!
//Element.getBoundingClientRect() 메서드는
//엘리먼트의 크기와 뷰포트에 상대적인 위치 정보를 제공하는 DOMRect 객체를 반환한다
console.log(navbarHeight); //104.5
//스크롤 이벤트 사용(스크롤시 이벤트 발생)
//document.addEventListener('동작',함수)을 냅다 변수에도 안넣고 작성시
//그냥 계속 동작하나 않하나 지켜보며 실행됨
document.addEventListener('scroll',() => {
//window는 브라우저의 창이고 document는 브라우저 창의 HTML 문서 객체입니다.
//즉, window객체 안에 document객체가 존재
// console.log(window.scrollY); //현재 스크롤 위치 알기(윈도우의 y값)
//이벤트 발생하면 navbar 색 바뀜
// navbar.classList.add('navbar--bold');
//색이 바뀐채로 고정시키려고
//+css
if(window.scrollY > navbarHeight){
//window.scrollY는 문서가 수직으로 얼마나 스크롤됐는지 픽셀 단위로 반환
navbar.classList.add('navbar--bold');
//classList 등장
}else{
navbar.classList.remove('navbar--bold');
}
//html에 navbar--bold란 클래스가 없는데
//classList :navbar클래스에 속성을 추가하겠다
//스크롤시 navbar--bold 생김
//<nav id="navbar" class="navbar--bold">
//클래스 여러개 쓸 수 있다 .navbar__menu__item active
//navbar__menu__item 과 active 두개! 띄어쓰기로 구분함!
});
//스크롤에 따른 메뉴바 고정
//메뉴 클릭시 해당 페이지로 이동
const navbarMenu = document.querySelector('.navbar__menu');
navbarMenu.addEventListener('click' ,(e) => {
//이벤트가 발생되면 매개변수 주지 않아도 특정값이 다 들어옴
//console.log(e);
const target = e.target;
const link = target.dataset.link;
//dataset등장!!!
//방어코드
if (link == null){
return;
}
// console.log(link);
navbarMenu.classList.remove('open'); //토글할때 추가했음
scrollIntoView(link);
})
//토글, 모바일 메뉴 버튼 설정 //+css
const navbarToggleBtn = document.querySelector('.navbar__toggle-btn');
navbarToggleBtn.addEventListener('click' ,(e) => {
navbarMenu.classList.toggle('open');
});
function scrollIntoView(selector){
const scrollIo = document.querySelector(selector);
scrollIo.scrollIntoView({behavior: 'smooth'});
}
//element.scrollIntoView(); :element 위치로 화면 스크롤됨
//behavior: 'smooth' - 부드럽게 스크롤링 됨
//문제. 연락주세요 버튼 누르면 번호 있는 페이지로 스크롤 되게끔
const homeContactBtn = document.querySelector('.home__contact');
homeContactBtn.addEventListener('click', () => {
scrollIntoView('#contact');
})
const home = document.querySelector('.home__container');
const homeheight = home.getBoundingClientRect().height;
//contact 버튼
//문제. 위로 가는 버튼 //+css
const arrowUp = document.querySelector('.arrow-up');
document.addEventListener('scroll' , () => {
if(window.scrollY > homeheight / 2){
arrowUp.classList.add('visible');
}else{
arrowUp.classList.remove('visible');
}
//스크롤시 home__title 투명도
home.style.opacity = 1 - window.scrollY / homeheight;
});
arrowUp.addEventListener('click', () => {
scrollIntoView('#home');
})
//프로젝트 버튼 누르면 선택한 프로젝트 보이기
const workBtnContainer = document.querySelector('.work__categories');
const projectContainer = document.querySelector('.work__projects');
const projects = document.querySelectorAll('.project');
workBtnContainer.addEventListener('click', (e) => {
const filter = e.target.dataset.filter || e.target.parentNode.dataset.filter;
if(filter == null){
return;
}
const active = document.querySelector('.category__btn.selected');
if(active != null){
active.classList.remove('selected');
}
e.target.classList.add('selected');
//애니메이션 줄려고,+css
projectContainer.classList.add('anim-out');
setTimeout(() => {
projects.forEach((project) => {
console.log(project.dataset.type);
if(filter === '*' || filter === project.dataset.type){
project.classList.remove('invisible');
}else{
project.classList.add('invisible');
}
});
projectContainer.classList.remove('anim-out');
}, 300);
});
//네비바 메뉴 호버시
//모든 요소 체크할 번호,배열로
const sectionIds = [
'#home',
'#about',
'#skills',
'#work',
'#testimonials',
'#contact'
];
// map등장!!
const sections = sectionIds.map((id) => document.querySelector(id));
//#home인 객체를 찾아 집어넣고를 반복
// console.log(sections);
//메뉴 위에 다섯개 가져윰
const navItems = sectionIds.map((id) => document.querySelector(`[data-link="${id}"]`));
// console.log(navItems);
let selectedNavIndex = 0;
let selectedNavItem = navItems[0];
function selectNavItem(selected){
selectedNavItem.classList.remove('active');
selectedNavItem = selected;
selectedNavItem.classList.add('active');
}
//아이템 실행시켜주는
//마우스 휠
const observerOptions = {
root : null,
rootMargin : '0px',
threshold : 0.3
}
const observerCallback = (entries, observer) => {
entries.forEach((entry) => {
if(!entry.isIntersecting && entry.intersectionRatio > 0){
console.log('y');
const index = sectionIds.indexOf(`#${entry.target.id}`);
// console.log(index);
if(entry.boundingClientRect.y < 0){
selectedNavIndex = index + 1;
}else{
selectedNavIndex = index - 1;
}
console.log(selectedNavIndex);
}
})
}
const observer = new IntersectionObserver(observerCallback, observerOptions);
sections.forEach((section) => observer.observe(section));
window.addEventListener('wheel' , () => {
if(window.scrollY === 0){
selectedNavIndex = 0;
}else if(
window.scrollY + window.innerHeight === document.body.clientHeight
) {
selectedNavIndex = navItems.length -1;
}
selectNavItem(navItems[selectedNavIndex]);
});
'웹 개발 > 🌐 JavaScript' 카테고리의 다른 글
fetch함수 (0) | 2023.05.19 |
---|---|
동기, 비동기(콜백함수) (2) | 2022.11.26 |
JavaScript | promise,async,json,fetch (0) | 2022.11.17 |
JavaScript | 주석,에러처리,index,콜스택,settimeout,비동기 (0) | 2022.11.17 |
JavaScript | 이벤트타입,이벤트리스너,이벤트객체,이벤트전파,iterable,generator,spread,set,map,operator (0) | 2022.11.11 |