본문 바로가기
Udemy - The web developer camp

JavaScript DOM event

by Hanachoi 2022. 12. 1.

#Intro Events(Responding to user inputs and actions)

  • It is a key to make interactive website doing anything in response to what user's doing. 
  • It reacts when users do such as clicks, drags, drops, hovers, scrolls etc.
  • clicks/drags/drops/hovers/scrolls/ form submission/ key presses/ focus/ blur/ mouse whell/ double click/ copying/ pasting /audio start/ screen reszie/ printing etc

 

# Inline event

  • There's three ways to respond user events.
  • First, You can write a code in HTML which is not really used in common
  • Let's say you want to make any event when users click something.
  • When you used this way, you need to care about quotation marks and this make up is getting long. Also when you want to write multiple lines, you need to use semicolon as well.
<button onclick = "alert('you clicked me~') ; alert('stop clicking me')">Click ME!</button>;
  • This code works for only first markup, and if you want to apply for other elements on HTML, you need to copy and paste for every single element. 

 

# onclick event

  • you can work it on JS. 
  • select the HTML property first and then you can add onclick property and write down inline function which runs whenever user clicked the button.
  • This way is easier to try to select multple buttons and repeat the process. You can loop over them and give each one onclick.
<body>
	<button id="v2">Cilcik me(2nd version)</button>
    <script src = 'app.js'></script>
    </body>
const btn = document.querySelector('#v2')

btn.onclick = function(){
	console.log('You clicked button');
    console.log('I hope it worked!');
}
  • We are not running the function directly.  We just defiend the functin and pass it to onmouseenter or onclick. This function exists for the purpose of being called eventually when this button is clicked.
  • We are not exectueing this functions, but just set up properties to be functions. 
  • you can make a function and set up this functon with properties 
function scream(){
	console.log('AAAAAHHHHH');
    console.log('stop touching me!');
}

btn.onmouseenter = scream;
  •  Even though you want to write one line code, you need to cover it with function, otherwise it is going to be runned right away. What you need to do is set up onclick property on a function itself. It is not to execute function right away. 

 

# addEventListener

  • addEventListener specify the event type and al callback to run. You can pass any of events you want to pass
  • first arguement is for the string we want to pass in, and the second argument is for callback function that we want to execute when the event happens. 
const btn = documeny.querySelector('h1');

btn.addEventListener('click',() =>{
	alert('You clicked me!!')
})
  • You can go to NDN to browse what events there are. Just the first argument must be one of the events. Also the second arguement must be a function you want run.
  • For the second argument, you can use regular function, arrow function and variable that has function already.
  • Then why do you need to use addEventListener then onclick event? Ii might look better to use onclick event cuz it looks shorter. But onclick event cannot set up two different callback function. 
//html 
<button id= "tas">Twist and shout!</button>

//JS

function twist(){
	console.log('TWIST');
}

function shout(){
	console.log('SHOUT');
}

const tasButton = document.querySelector('#tas');

tasBUtton.onclick = twist;
tasBUtton.onclick = shout;
// just shout is working. onclick can run just one callback function. shout is overwritten.
  • But with addEventListener, you can run multiple functions. 
tas.addEventListener('click',twist)
tas.addEventListener('click',shout) // both are working
  • Also there are a bunch of other arugments to pass in for different options. This options object can contain different options including once etc.
  • addEventListener has more flexibility 
tas.addEventListener('click',twist,{once : true}) // It will be working only once 
tas.addEventListener('click',shout) // both are working

 

 

# event and 'this' keyword

  • Let's say you want to make a bunch of buttons and <h1> tags that color changed whenever it clicked,
const clicks = document.querySelectorAll('button');
const h1s = document.querySelectorAll('h1');

const makeRandomColor = ()=>{
  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})`;
}

for(let click of clicks){
    click.addEventListener('click', function(){
      click.style.backgroundColor = makeRandomColor();
      click.style.color = makeRandomColor();

  })
}


for(let h1 of h1s){
  h1.addEventListener('click',function (){
      h1.style.backgroundColor = makeRandomColor();
      h1.style.color = makeRandomColor();
    })
}
  • On this code, you can see some duplicated codes for the same function. The only difference is that they have different selector such as h1 and button. So you can make generic function to let it do 
  • You can make another function to make it work for changing color
  • Inside of event Handler, callback function has the key word 'this' for whatever it is clicked on. Wheverever the event happend that function will refer to keyword 'this'.
  • this keyword depends on the execution context or the invocation context.
for(let h1 of h1s){
  h1.addEventListener('click',function (){
      this.style.backgroundColor = makeRandomColor();
      this.style.color = makeRandomColor();
    })
}

// you can change h1 into this keyword, but still working well
    •  You can seperate this function and this function has this keyword, so it is going to work both of loops 
for(let click of clicks){
    click.addEventListener('click', colorlize)
}


for(let h1 of h1s){
  h1.addEventListener('click',colorlize)
}

function colorlize(){
  this.style.backgroundColor = makeRandomColor();
  this.style.color = makeRandomColor();

}

 

 

# keyboard event and event object.

  • We thought we didn't have any parameters in callback function, but event object was always automatically passed in callback function so far. We are not using it or capturing it but always passed in this function every single time.
  • You can pass in event or e or evt in parentheses in callback funtion. 
  • It is mouse event and has something like client X or client Y etc. it is related to window and think of it as coordinates.
document.querySelector('button').addEventlistener('click',(e)=>{

})
  • We can use this event object for events that you can add some animations on clicked spot or decorations. 
  • We often need eventObject for keyboard event. We frequently need to know what key is pressed and evenyObject has this information 
const input= document.querySelector('input');
input.addEventListener('keydown',()=>{
  console.log('keydown')
})

input.addEventListener('keyup',()=>{
  console.log('keyup')
})
  • You can see keyboard event object which has informations about respectible events.
  • You should focus on code , key properties 
const input= document.querySelector('input');
input.addEventListener('keydown',(e)=>{
  console.log(e)
})
const input= document.querySelector('input');
input.addEventListener('keydown',(e)=>{
  console.log(e.code)
  console.log(e.key)
})


a // key : a //code : keyA
  • code reflects the actual location on keyboard. 
  • If you want to know what is typed on keyboard actually, you can use key.  If you want to know actual location on keyboard and then you can use code.
  • If the user use another language, and he pressed 'a' on keyboard, key would be diffrent language charactor, but code is still keyA.
  • You can check what users use on keyboard.
window.addEventListener('keydown', function (e){
	console.log(e.code)
} )
  • If you make a game, you can use it with switch statement.
window.addEventListener('keydown', function (e){
	switch(e.code) {
    	case 'ArrowUp' :
        	console.log("UP")
            break;
        case 'ArrowDown' :
        	console.log("down")
            break;
    }
})
  • To recap, every event listener handlers pass in automatically, and we don't call this function but whenever it is called, it is passed. We can add parameter and capture it 

 

#Form events and preventDefault 

  • It is important part to make web application. We usually have some form and use what users submit. 
  • You can make a form without JS by setting up action which is URL that data is located 
<form action = "/dogs">
	<input type ="text" name ="username">
    <input type ="password" name ="password">
    <button>submit</button>
</form>
  • Without JS, this data will be submitted to /dogs. whatever action is, the data will be sent to this part.
  • With JS, when you submit a form, you need to listen for form submition. whenever you submit the form, the page will be changed into the action page that data will go.   
  <form action="/dogs" id="tweetForm">
   <input type="text" name="username" placeholder="username">
   <input type="text" name="tweet" placeholder="tweet">
   <button>post tweet</button>
  </form>
//js

const tweetForm = document.querySelector('#tweetForm');
tweetForm.addEventlistener('submit', function(e){
	console.log('submit')
})

//cannot found 404
  • Becuase we are still moving to the next page, and still getting some requests, the page keeps chagned. 
  • So we can use JS not to do default behavior that change the page into URL that data goes.
  • Add preventDefault and it wil stope the default behavior. In this case, event in on the object, so you need to write down e.preventDefault(parameter)
const tweetForm = document.querySelector('#tweetForm')
tweetForm.addEventListener('submit', function(e){
  console.log('submit!')
  e.preventDefault();
})
  • You can add new date from the form to <ul>.
  • You need to know how to extract the data from the form. 
document.querySelectorAll('input')[1].value

//be able to get the value from the second input box
const tweetForm = document.querySelector('#tweetForm')
tweetForm.addEventListener('submit', function(e){
  const usernameInput = document.querySelectorAll('input')[0];
  const tweetInput = document.querySelectorAll('input')[1];
  console.log(usernameInput.value, tweetInput.value)
  e.preventDefault();
})
  • You can access elements of the collection of the form.
  • But in this example, if you change the order of input boxes, the data you want to get will be also chagned as well. If you give each element thier name which is set up as a property name in HTML. 
  • Also if you have many values, selecting each input individually could be annoying. 
  • So you can access form.username and reach out quickly. 
const tweetForm = document.querySelector('#tweetForm');
const tweetContainer = document.querySelector('#tweets');

tweetForm.addEventListener('submit', function(e){
  e.preventDefault(); //페이지안바뀌게

  const usernameInput = tweetForm.elements.username;
  const tweetInput= tweetForm.elements.tweet;
  addTweet(usernameInput.value, tweetInput.value)
  usernameInput.value='';
  tweetInput.value='';

})

//새로운 리스트 만들어서 값을 넣어주는 함수

const addTweet = (username, tweet) =>{
  const newTweet = document.createElement('li');  
  const bTag = document.createElement('b');
  bTag.append(username)
  newTweet.append(bTag);
  newTweet.append(`-${tweet}`)
  tweetContainer.append(newTweet)
}

 

# Input and change event.

  • These are related to input and form event. 
  • Every time input is updated, something is supposed to be happend. 
  • When you use keydown or keyup event, something happend when users press arrow keys or shift keys. Also If users use copy and paste or use voice over utility or something, it is considered typing even though it is not physical pressing.
  • The 'change' event only fires when you actually blur the input.
  • you should think whenever you leave the input  container and changed something in it, it is a change. 
const input = document.querySelector('input');

input.addEventListener('change',function(e){
  console.log('ddd')
})
  • When you want to something fires when value in input changed, you can use input event.
  • The event is happend not only something is blurred in input, but also whatever typed in input container.
  • It is not working when you press shift or arrow keys because it doesn't affect anything in input box.
  • Voice utility reader or screen reader also works.
  • You can sync <h1>tag with whatever you typed. 
const input = document.querySelector('input');
const h1= document.querySelector("h1");

input.addEventListener('input',function(e){
  h1.innerText = input.value;
 
})

 

 

# Event bubbling

  • The evenet triggered first some elements and triggered another element as well. 
  • Think of bubbles rising up in a fish tank. They go from the bottom all the way up to the top or to the higher level, highest level to the surface. 
  • In this case, when you press the button, it triggers other onclick functions as well, so all of the alerts are poping up.
<section onclick = alert('Section clicked')>
    <p onclick=alert('P clicked')> I am a paragraph
        <button onclick= alert('button clicked')>click</button>
    </p>
</section>
  • Let's say you want to change the background color whenever you click <button> and it is nested in <div> which has toggle event listener. The problem here is whene you click the <button>, <div> is also toggled so it hids at the same time you clicke the <button>. It is event bubbling
const button = document.querySelector('#changeColor');
const container = document.querySelector('#container'); //<div> in HTML

button.addEventListener('click',function(){
	container.style.backgroundColor = makeRandColor();
})
container.addEventLitener('click',function(){
	container.classList.toggle('hide');
})

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})`;
}
  • There is a easy way to stop bubbling by using stopPropagation()
  • stopPropagation() make it no longer trigger the bubbling which means it is the final step on this code.
const button = document.querySelector('#changeColor');
const container = document.querySelector('#container'); //<div> in HTML

button.addEventListener('click',function(e){
	container.style.backgroundColor = makeRandColor();
    e.stopPropagation(); // stop triggering bubbling
})
container.addEventLitener('click',function(){
	container.classList.toggle('hide');
})

 

 

#Event delegation

  • Event delegation means we are going to add our event listener to some element that is a parent ouf our allies.
  • Let's say you want to delete any <ul> markup when you click it. So you can add some event listener over it
  • you can find out what element is clicked is that target elements on event object.
tweetContainer.addEventListener('click',function(e){
  e.target.remove();
})
  • e. target is actually what clicked is.
  • You need to check what is clicked or what is the target on because something else can be affected by any event.
  • You can check it like this
console.dir('e.target') 

e.target.nodeName === 'LI' &&e.target.remove(); 
//노드네임이 LI가 아니면  &&e.target.remove(); 부분은 실행 안됨
  • It's useful in situations like this where we have elements that may not be on the page at the time our evet listeners are added so we can add event listeners to some parent elements.

'Udemy - The web developer camp' 카테고리의 다른 글

Asynchronous JavaScript  (0) 2022.12.10
JavaScript DOM  (0) 2022.11.17
JavaScript new syntax  (0) 2022.11.12
JavaScript Callback and Array Methods  (0) 2022.10.25
JavaScript function level up  (0) 2022.10.13

댓글