23.7.19 TIL

김진주·2023년 7월 19일
0

TJL(Today Jinju Learned)

목록 보기
26/35

📌Events (with UI)

🏷️Event Handling

HTML 속성 :

좋은 방법은 아님 가독성이 떨어지고 유지보수가 어려워짐
제일 큰 이슈: 여러 개의 이벤트를 넣을 수 없고 단 하나의 이벤트만 들어감 하나의 함수만 실행할 수 있음

DOM 프로퍼티 : element.onclick = handler

onclick은 지양!!
속성으로 넣는 것은 실행 시켜줘야 하고
프로퍼티로 넣는건 실행 시키지 않아도 됨

메서드 : element.addEventListener(event, handler[, phase])

두 개는 다른 함수
바로 함수를 불러서 사용하는 건 좋지 않다 변수에 담아서 사용해야 한다.

🏷️bubbling & capturing

버블링

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

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);

currentTarget과 target의 차이점

다른 폴더에서 다른 깃에 들어있는 폴더 불러오기

$npx degit https://github.com/pearlKinn/lion-javascript.git/client/lib#02.dom client/lib


다른 폴더에서도 내가 만든 유틸함수를 가져와서 사용할 수 있다.

다른 예제로 알아보는 delegation

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);
profile
진주링딩동🎵

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

정말 깊이 있는 글이었습니다.

답글 달기