좋은 방법은 아님 가독성이 떨어지고 유지보수가 어려워짐
제일 큰 이슈: 여러 개의 이벤트를 넣을 수 없고 단 하나의 이벤트만 들어감 하나의 함수만 실행할 수 있음
onclick은 지양!!
속성으로 넣는 것은 실행 시켜줘야 하고
프로퍼티로 넣는건 실행 시키지 않아도 됨
두 개는 다른 함수
바로 함수를 불러서 사용하는 건 좋지 않다 변수에 담아서 사용해야 한다.
const section = getNode('section');
const article = getNode('article');
const p = getNode('p');
section.addEventListener('click', () => {
console.log('%c section', 'color:orange');
});
article.addEventListener('click', (e) => {
// e.stopPropagation();
console.log('%c article', 'color:dodgerblue');
});
p.addEventListener('click', (e) => { // p -> article -> section
// e.stopPropagation(); // 퍼져 나가는 것을 막음!!
console.log('%c p', 'color:hotpink');
});
section.addEventListener('click', () => {
console.log('section');
}, true);
article.addEventListener('click', () => {
console.log('article');
}, true);
p.addEventListener('click', () => { // 거꾸로 올라가는 것 section -> article -> p
console.log('p');
}, true);
Event delegation을 사용하는 이유
const btnA = getNode('.a')
const btnB = getNode('.b')
const btnC = getNode('.c')
btnA.addEventListener('click', () => {
})
btnB.addEventListener('click', () => {
})
btnC.addEventListener('click', () => {
})
이런식으로 이벤트를 생성하면 리소스를 많이 잡아 먹기 때문에 이벤트 위임을 사용한다!
const container = getNode('.container');
function handleDelegation(e) {
// console.log(this); // 일반함수일 때 === this / container (이벤트가 걸린 대상)
// console.log(e.currentTarget); // 일반함수일 때는 container (이벤트가 처음 걸린 대상)
// console.log(e.target); // 마우스가 처음 만난 대상을 가리킴
let target = e.target;
let li = target.closest('li');
if(!li) return; // 부모 스코프에서 li를 찾지 못하면 return 하여 함수 종료
let className = attr(li, 'class');
let dataName = attr(li, 'data-name') //target.dataset.name
// console.log(target.closest('li')); // 상위 부모 중에서 가장 가까운 li를 찾아줌
if(className === 'home') {
console.log('홈 실행');
}
// target.getAttribute('class'); 속성 가져오는 메소드
//^ if (className === 'a') {
//^ console.log('A버튼 클릭');
//^ }
//^ if (className === 'b') {
//^ console.log('B버튼 클릭');
//^ }
//^ if (className === 'c') {
//^ console.log('C버튼 클릭');
//^ }
//^ if (className === 'd') {
//^ console.log('D버튼 클릭');
//^ }
// if(dataName === 'A') {
// console.log('A버튼 클릭');
// }
}
const arrowHandleDelegation = (e) => {
console.log(this); // window
console.log(e.currentTarget); // container 이벤트가 걸린 현재 대상
console.log(e.target); // button 누르면 button 수집 가능
}
container.addEventListener('click', handleDelegation);
$npx degit https://github.com/pearlKinn/lion-javascript.git/client/lib#02.dom client/lib
다른 폴더에서도 내가 만든 유틸함수를 가져와서 사용할 수 있다.
const navigation = getNode(".navigation");
//^ const list = getNodes(".navigation li");
const visualImage = getNode('.visual img ')
function handleSlider(e) {
e.preventDefault();
const target = e.target.closest("li");
const anchor = e.target.closest("a"); // a 태그에 경로가 설정되어 있기 때문에 href 값이 필요해서 부름
if (!target || !anchor) return;
// 내가 선택하지 않은(모든 li) li에게 is-active 클래스 제거해주세요
// 1. getNodes => nodeList
// 2. children(자식들을 다 가져옴) => htmlcollection
// 3. for / forEach => classList.remove (removeClass)
//% forEach를 사용하기 위해 배열로 만듦 / 만들지 않으면 for...of문을 사용하면 됨
const list = [...navigation.children] // navigation.children === this.children === e.currentTarget.children
const index = attr(target, 'data-index') // 선택한 대상의 data-index값을 가져와주세요.
// 내가 선택하지 않은(모든 li) li에게 is-active 클래스 제거해주세요
// 1. getNodes => nodeList
// 2. children(자식들을 다 가져옴) => htmlcollection
// 3. for / forEach => classList.remove (removeClass)
list.forEach(li => removeClass(li, 'is-active'))
// 내가 선택한 li에게 is-active 클래스를 넣어주세요
addClass(target, "is-active"); // 내가 선택한 li에게 is-active 클래스를 넣어주세요
attr(visualImage ,'src', `./assets/part01/${data[index - 1].src}`) // src의 값을 index로 바꾼다.
attr(visualImage ,'alt', `${data[index - 1].alt}`) // alt 값을 변경한다.
}
navigation.addEventListener("click", handleSlider);
정말 깊이 있는 글이었습니다.