[프로젝트] 인스타그램 클론코딩 #6. JS 적용하기 - event delegation

UkiUkhui·2022년 8월 20일
0

Project 해보자!

목록 보기
7/8

6. event delegation

  • 이벤트를 위임해 부모에게 전달
    • 하트 클릭 : 하트 대상에게 on클래스를 주어 하트에 불이 들어오게 함
    • 클래스를 주어야 할 요소 개수가 많아지면 : 모든 요소들에 이벤트를 반복적으로 추가해야함
  • 이벤트를 모두 포함하는 컨텐츠 박스 추가 후 이벤트를 위임하는 방법임
    • 게시물 : 하트, 댓글, 공유, 게시 버튼 등 이벤트를 추가해야할 요소들

1) main.js에 deligationFunc 추가

const deligation = document.querySelector(".contents_box");

// heart.addEventListener('click', function () {
//     console.log('하트누름 정상작동');
//     heart.classList.toggle('on');
// });

function deligationFunc(e) {
    let elem = e.target; //클릭 요소 가져오기
    console.log(e.target);
    console.log(elem);

    while (!elem.getAttribute('data-name')) {
        //elem의 부모를 찾음
        elem = elem.parentNode;
        if (elem.nodeName === 'BODY') {//body까지 이벤트가 없는 경우
            elem = null;
            return;

        }//data-name을 가진 속성을 찾을때까지 부모에게 접근 반복
    }

    if (elem.matches('[data-name="heartbeat"')) {
        console.log('하트누름');
    } else if (elem.matches('[data-name="bookmark"')) {
        console.log('북마크누름');
    } else if (elem.matches('[data-name="share"')) {
        console.log('공유누름');
    } if (elem.matches('[data-name="more"')) {
        console.log('더보기누름');
    }

    elem.classList.toggle('on'); //on 클래스 주기
}
  • e.target을 통해 클릭요소 가져오기

    • 클릭요소의 속성을 가져와 data-name 확인
    • 가져온 요소와 data-name이 일치하는 경우 로그
    • 해당 요소에 on 클래스 추가
    • css: on함수 발생 시 이미지변경
  • index.html

    • data-name 일치시키기
  • css

    • delegation을 통해서 .on 클래스가 추가
    • heart_btn.on 이 아니라 .sprite_heart_icon_outline으로 수정
/*.heart_btn.on .sprite_heart_icon_outline*/
.sprite_heart_icon_outline.on
{/*on 클래스 추가 시 이미지 변경*/
    background: url('../imgs/background01.png') no-repeat -26px -261px;
	width: 24px;
	height: 22px;
}

2) 새로고침 이벤트 추가

  • 새로고침하면 웹 페이지의 최상단으로 이동하는 기능 추가
const header = document.querySelector('#header');
const sidebox = document.querySelector('.side_box');
const variableWidth = document.querySelectorAll(".contents_box .contents");
//SelectorAll을 통해 모든 요소를 가져옴

const deligation = document.querySelector(".contents_box");

// heart.addEventListener('click', function () {
//     console.log('하트누름 정상작동');
//     heart.classList.toggle('on');
// });

function deligationFunc(e) {
    let elem = e.target; //클릭 요소 가져오기
    //console.log(e.target);
    console.log(elem);

    //잘못 클릭함
    while (!elem.getAttribute('data-name')) {
        //elem의 부모를 찾음
        elem = elem.parentNode;
        if (elem.nodeName === 'BODY') {//body까지 이벤트가 없는 경우
            elem = null;
            return;

        }//data-name을 가진 속성을 찾을때까지 부모에게 접근 반복
    }

    if (elem.matches('[data-name="heartbeat"')) {
        console.log('하트누름');
    } else if (elem.matches('[data-name="bookmark"')) {
        console.log('북마크누름');
    } else if (elem.matches('[data-name="share"')) {
        console.log('공유누름');
    } if (elem.matches('[data-name="more"')) {
        console.log('더보기누름');
    }

    elem.classList.toggle('on'); //on 클래스 주기
}

function resizeFunc() {
    if (pageYOffset >= 10) {
        let calcWidth = (window.innerWidth * 0.5) + 167; //웹페이지 기반 위치 재조정
        sidebox.style.left = calcWidth + 'px';
    }

    if (matchMedia('screen and (max-width : 800px)').matches) {
        //여러 개의 컨텐츠 박스가 있으므로 배열 활용
        for (let i = 0; i < variableWidth.length; i++) {
            variableWidth[i].style.width = window.innerWidth - 20 + 'px';
        }
    } else {
        for (let i = 0; i < variableWidth.length; i++) {
            if (window.innerWidth > 600) //디폴트값이 614이므로 그 이상 커지지 않게 하기 위함
                variableWidth[i].removeAttribute('style');
        }
    }
}

function scrollFunc() {
    //console.log(pageYOffset);
    if (pageYOffset >= 10) {//드래그할 경우
        header.classList.add('on');
        sidebox.classList.add('on');
        resizeFunc();
    } else {
        header.classList.remove('on');
        sidebox.classList.remove('on');
        sidebox.removeAttribute('style');
    }
}

setTimeout(function () {
    scrollTo(0, 0);
}, 100); //새로고침하면 화면이 제일 위로 가게 함

if (deligation) {
    deligation.addEventListener('click', deligationFunc);
}


window.addEventListener('resize', resizeFunc);//resize 이벤트 발생 시 resizeFunc 실행
window.addEventListener('scroll', scrollFunc);
profile
hello world!

0개의 댓글