JS

[JS][Udemy] DOM event +

winter17 2023. 3. 27. 17:54

► Events

  • 코드를 이용해 동작하는 행동 → 스크롤, 마우스 동작 시 새로운 요소 생성 등

 

 

► Inline Event

  • html안에 인라인을 넣는 방법 → 권장하지 않음!
<body>
    <section onclick="alert('section clicked')">
        <p onclick="alert('paragraph clicked')">
            I am a paragraph:
            <button onclick="alert('button clicked')">Click</button>
        </p>
    </section>
</body>

'click' 버튼을 눌렀을 때 'button clicked' 경고창이 나타나고 확인을 누르면 'paragragh clicked' → 'section clicked' 경고창이 이어서 나타남

 

 

 

► addEventListener

// index.html
<div id="container">
        Click To Hide
        <button id="changeColor">Change Color</button>
</div>


// app.js
const button = document.querySelector('#changeColor'); // button id 선택
const container = document.querySelector('#container'); // div id 선택


button.addEventListener('click', function (e) { // button이 클릭되었을 때 다음 함수 실행
    container.style.backgroundColor = makeRandColor(); // div의 색상을 랜덤으로 변경
    e.stopPropagation(); // 위의 이벤트가 전달되는 것을 막음
})

// div가 클릭되었을 때 숨기기
container.addEventListener('click', function () {
    container.classList.toggle('hide'); 
})

// 랜덤 컬러 함수 : rgb 색상을 랜덤으로 생성해서 반환
const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}

⎣ 왜 인라인 이벤트인 onclick을 사용하지않고 addEventListener를 통해 click을 사용할까?

onclick은 동일한 이벤트에 대해 두 개의 서로 다른 콜백 함수를 저장할 수 없기 때문에

다시말해,

button.onclick = console.log('hello') 

 

button.onclick = console.log('hi')

위처럼 차례대로 선언되었다면 마지막에 선언한것만 실행이 됨

하지만, addEventListener는 원하는 만큼 콜백 함수를 사용할 수 있다

 

 'change color' 버튼 누를때 마다 색상 변경됨

 

⎣ 버튼이외의 공간을 클릭할 경우 div로 설정된 부분이 전부 사라짐  

 

// index.html
<body>
    <h1>Welcome!</h1>
    <button id="changeColor">Click Me</button>
</body>

// app.js
const btn = document.querySelector('button') // button 선택
const h1 = document.querySelector('h1') // h1 선택
btn.addEventListener('click', function (){ // button을 클릭했을 때 함수 실행
    const newColor = makeRandColor() // 랜덤컬러 변수 정의
    document.body.style.backgroundColor = newColor // body의 색상이 랜덤으로 변경
    h1.innerText = newColor // h1 텍스트가 newColor 변수로 바뀌는데
                            // 아래에서 newColor의 변수는 rgb컬러 번호로 저장해둠
})

const makeRandColor = () => { // 랜덤컬러 함수
    const r = Math.floor(Math.random() * 255) 
    const g = Math.floor(Math.random() * 255)
    const b = Math.floor(Math.random() * 255)
    return newColor = `rgb(${r}, ${g}, ${b})` // rgb 컬러를 위에서 정해둔 newColor변수에 저장
}

 

  'Click Me' 버튼 누를때 마다 배경색상과 rgb 색상번호가 바뀜

 

 

 

► Event & 'this' keyword

    <style>
        button {
            width: 100px;
            height: 100px;
            margin: 20px;
        }
    </style>
</head>

<body>
    <button>CLICK</button>
    <button>CLICK</button>
    <button>CLICK</button>
   

    <h1>Click Me!</h1>
    <h1>Click Me!</h1>
    <h1>Click Me!</h1>
// 랜덤 컬러 함수 생성
const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}

// 버튼 태그 선택
const buttons = document.querySelectorAll('button');

// 버튼 태그 'click' 클릭 시 colorize 함수 실행
// colorize 함수는 배경색상 / 색상 랜덤으로 변경
for (let button of buttons) {
    button.addEventListener('click', colorize)
}
// h1 태그 선택 후 반복문으로 h1태그('click me') 선택 시
// 위와 같이 색상 변경 
const h1s = document.querySelectorAll('h1');
for (let h1 of h1s) {
    h1.addEventListener('click', colorize) 
    // h1을 this키워드로 바꿔서 사용해도 괜찮지만 중복된다는 사실을 변함이 없기 때문에 
    // 랜덤 컬러부분을 따로 함수로 만들어주는게 보기 편하다
}

// colorize 함수 
function colorize() {
    this.style.backgroundColor = makeRandColor(); // h1, button 제너릭 함수라서 엑세스 불가능
    this.style.color = makeRandColor(); // 따라서 this 키워드 사용
}
// this 키워드를 사용하지 않았을 경우
// 중복이 많이 발생

for (let button of buttons) {
    button.addEventListener('click', function() {
        button.style.backgroundColor = makeRandColor();
        button.style.color = makeRandColor();
    })
}

const h1s = document.querySelectorAll('h1');
for (let h1 of h1s) {
    h1.addEventListener('click', function() {
        h1.style.backgroundColor = makeRandColor();
        h1.style.color = makeRandColor();
    })
}

클릭할 때마다 색상이 바뀜

 

 

 

► Event object

button을 선택했을 때의 이벤트 객체 정보

 

⎣ 이벤트에 대한 정보를 담고 있는 객체

 

// input 태그 선택
const input = document.querySelector('input');
input.addEventListener('keydown', function (e) {
    console.log(e.key) // key : 사용자가 누르는 키 : 사용자가 변경할 수 있음
    console.log(e.code) // code : 키보드에서의 실제 위치 : 기본 값
})

 

 

 한글 'ㅁ'을 입력하면 key A : 키보드 위치 출력

 

 

⎣ 영어 ' a' 를 입력하면 key A : 키보드 위치 출력

 

 

 

► Keyboard Event

<body>
    <button>CLICK</button>
    <input type="text">
    <script src="app.js"></script>
</body>
// button 태그 선택 후 click할때 evt 함수실행
document.querySelector('button').addEventListener('click', function (evt) {
    console.log(evt)
})

// window 전체에 대한 이벤트 리스너 추가
// 키다운, 키업을 사용하려면 window.addEventListener
window.addEventListener('keydown', function (e) {
    switch (e.code) { // code는 키보드 위치
        case 'ArrowUp': // 위 방향키
            console.log("UP!");
            break;
        case 'ArrowDown': // 아래 방향키
            console.log("DOWN!");
            break;
        case 'ArrowLeft': // 왼쪽 방향키
            console.log("LEFT!");
            break;
        case 'ArrowRight': // 오른쪽 방향키
            console.log("RIGHT!");
            break
        default:  // 방향키 이외의 것들
            console.log("IGNORED!")
    }
})

 

⎣  방향키 이외의 다른 것을 입력하면 'IGNORED!'

⎣ break 하지않으면 계속 출력됨 [switch 조건문] : 2023.03.13 - [JS] - [JS][udemy] JS 판단 내리기

 

 

► Form Events & PreventDefault

// index.html
<body>
    <h1>Form Events</h1>

    <form action="/dogs" id="tweetForm">
        <input type="text" name="username" placeholder="username">
        <input type="text" name="tweet" placeholder="tweet">
        <button>Post Tweet</button>
    </form>

    <h2>Tweets:</h2>
    <ul id="tweets">

    </ul>
// app.js
const tweetForm = document.querySelector('#tweetForm');
const tweetsContainer = document.querySelector('#tweets');
tweetForm.addEventListener('submit', function (e) {
    e.preventDefault(); // action에 전송되는 것을 막음

    // const usernameInput = document.querySelectorAll('input')[0];
    // const tweetInput = document.querySelectorAll('input')[1];
    // 주석처리 된 부분과 결과는 같음 -> 다만 순서가 바뀌면 값도 바뀜
    // 방식이 다른 것인데 각 태그에 name을 부여함 -> 순서가 바껴도 괜찮음
    const usernameInput = tweetForm.elements.username;
    const tweetInput = tweetForm.elements.tweet;
    // value는 입력된 값을 페이지에 출력
    addTweet(usernameInput.value, tweetInput.value)
    // 입력값을 초기화
    usernameInput.value = '';
    tweetInput.value = '';
});

const addTweet = (username, tweet) => {
    // 새로운 태그 생성 li, b
    const newTweet = document.createElement('li');
    const bTag = document.createElement('b');
    // 자식요소로 넣어주기
    bTag.append(username) // bold 태그 안에 username (input태그)
    newTweet.append(bTag); // bold 태그 안에 li태그 
    newTweet.append(`- ${tweet}`) // li 태그 사이에 들어가는 글자 ' - 8670303'
    tweetsContainer.append(newTweet); // ul태그 안에 li태그
}
// <li><b>winter_k</b> - 8670303</li>

   입력하고 post tweet 클릭하면 tweets아래에 추가됨

 console.log(newTweet) 하면 위의 결과가 나타남 : bold 태그 안에 li 태그

 

 

 

► ChangeAndInputEvents

<!DOCTYPE html>

<head>
    <title>Input Event</title>
    <!--LEAVE THESE LINES ALONE, PLEASE! THEY MAKE THE LIVE PREVIEW WORK!-->
    <script src="node_modules/babel-polyfill/dist/polyfill.js" type="text/javascript"> </script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

</head>

<body>
    <h1>Enter Your Username</h1>
    <input type="text" id="username">
</body>

</html>
const h1 = document.querySelector('h1')
const usernameInput = document.querySelector('#username')

usernameInput.addEventListener('input', function (e) {
    const username = usernameInput.value
    h1.innerText = `Welcome, ${username}`
    if (username.length === 0) { // 아무것도 입력하지 않았을 때
        h1.innerText = 'Enter Your Username'
    }
})

 


 

► 이벤트 핸들링 / 버블링 / 캡처링 / 차단

  • 핸들링 : 사용자가 행하는 모든 동작
  • 바인딩 : 이벤트 핸들링을 하기 위해 이벤트를 받을 화면 요소를 선택하고 그 요소와 이벤트를 연결해주는 것
  • 버블링 : 하위요소에서 상위요소로의 이벤트 전파 방식
    • 다시말해, 자식요소에 발생한 이벤트가 상위의 부모요소에까지 영향을 미치는 것
  • 캡처링 : 상위요소에서 하위요소로의 이벤트 전파 방식
  • 차단 : 이벤트 버블링은 window까지 전달되는데 이를 막기위해서는 stopPropagation()메소드를 사용해 이벤트 전파 차단하면 됨
    • 이벤트 캡처링의 경우에 차단 메소드를 사용하면 최상위 요소의 이벤트만 동작시키고 하위 요소들로 이벤트를 전달하지 않음

 

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Building_blocks/Events

 

이벤트 입문 - Web 개발 학습하기 | MDN

이벤트(event)란 여러분이 프로그래밍하고 있는 시스템에서 일어나는 사건(action) 혹은 발생(occurrence)인데, 이는 여러분이 원한다면 그것들에 어떠한 방식으로 응답할 수 있도록 시스템이 말해주

developer.mozilla.org