안녕하세요.
Hynn 입니다.
이번 포스팅에서는 지난 실습예제에서 다루었던 Lotto 번호 생성웹 페이지에서 잠시 소개되었던, appEventListner 에 대해서 설명드리고자 합니다.
이 appEventListner 는 JavaScript 에서 자주 사용되는 기능이고, 이를 위해서 함수를 배웠다고 해도 과언이 아닐수도 있습니다.
근본적으로 이벤트를 생성하면, 함수를 호출해야하고, 그 호출되는 함수를 생각하는 대로 구현하려면, 결과적으로 함수를 잘 다루어야 하기 때문입니다.
===========
1. appEventListner 이해하기
2. 주요 Method 알아보기
3. 예제 작성해보기
===========
1. appEventListener 이해하기
appEventListener 는 JavaScript 에서말 그대로 add, Event, Listener 글자 그대로 Event 를 추가하여 시각적으로 보는 것입니다.
이 appEnventListener 는 Method 로서, EventTarget 이라는 인터페이스에 있는 Method 입니다. 이를 우리가 JavaScript 방식으로 표현하면, EventTarget.addEventListener() 가 될 것입니다. 하지만 appEventListener 역시 근본적으로는 Window, DOM 과 같은 최상위 객체 안에 포함된 Method 이기도 합니다.
물론 Event 를 부여하는 것이 꼭 appEventListener 를 사용하지 않아도 부여할 수 있는 방법이 존재합니다.
하지만 왜 이 appEventListener 가 유용하게 사용이 되는지를 설명드리도록 하겠습니다.
2. 주요 Method 알아보기
먼저 appEventListener 를 이해하기 위해서는 몇가지 Method 와 방법에 대해서 이해가 필요합니다.
Event를 생성하는 방법은 크게 3가지의 방법이 있습니다.
이를 표로 정리해보면 아래와 같습니다.
유형 | 설명 | 작성예제 |
HTML에 직접추가 | HTML Element 에 속성을 부여하는 형태로 추가합니다. |
<button type="submit" onclick="buttonclick()">Button</button>
|
On~ 생성 | JavaScript 에서 선언된 변수에 'Onclick' 과 같은 형태로 추가합니다. |
const btn = document.querySelector('#btn')
btn.onclick = buttonclick()
|
appEventListener | appEventListner Method 를 사용하여 추가한다 |
const btn = document.querySelector('#btn')
function letsevent(e){
console.log('Hello Hynn')
}
btn.addEventListener('click',letsevent)
|
하나씩 살펴보도록 하겠습니다.
2-1) HTML에 직접추가
<button type="submit" onclick="buttonclick()">Button</button>
이 형태를 사용하여 이벤트를 추가하면, 2가지의 단점이 존재합니다.
- 가독성의 문제가 발생합니다.
- 이벤트를 1개만 지정할 수 있습니다.
즉, 만약 작성자가 Click을 하면, 이벤트를 2개를 발동하려면 이 방법은 전혀 효과적이지 않습니다다.
사용자가 작성한 HTML 문서가 길면 길어질수록, 가독성의 문제가 발생합니다.
일반적으로 이벤트를 부여한다면, 대상의 HTML Element 속성에 ID,Class 등이 부여되어 있을테고, 또 다른 속성들이 부여될 경우, 가독성에 현저한 영향을 미칠 수 밖에 없기 때문입니다.
2-2) On~ 생성
const btn = document.querySelector('#btn')
btn.onclick = buttonclick()
이 형태의 경우, 가독성의 측면에서는 다소 개선되었다고 할 수 있습니다.
이 두번째 방법부터는 HTML 문서에 직접 작성하는 것이 아니라 연결된 JavaScript 파일에서 별도로 작성하는 것이기 때문이죠.
그리고 이 방법부터는 DOM 을 이용해서 이벤트를 부여하고자 하는 Element 를 선택한 변수를 선언하고, 그 선언한 변수에 이벤트를 부여하는 형태로의 작성을 하기 시작합니다.
하지만 이 방법 역시 하나의 변수에, 하나의 이벤트, 즉 여러개의 이벤트를 부여할 수 없다는 단점이 여전히 남아 있습니다.
2-3) appEventListner
const btn = document.querySelector('#btn')
function letsevent(e){
console.log('Hello Hynn')
}
btn.addEventListener('click',letsevent)
위의 각각의 단점을 모두 개선한 것이 바로 appEventListener 입니다.
가독성의 문제를 해결하기 위해 HTML 과 JavaScript 를 분리해서 작성하였고, 하나의 변수에 여러개의 이벤트를 부여할 수 있습니다.
이전 포스팅에서 사용했던 Lotto 생성에 사용했던 appEventListener 를 가지고 설명하도록 하겠습니다.
const btn = document.querySelector('#submit')
const LottoDisplay = document.querySelector('#lottonum')
const LottoBox = document.querySelectorAll('#backarea>#lottonum > li')
const Payinfo = document.querySelector('#payinfo')
const Info = document.querySelector('#info')
function lottoHandler(e){
const randomLotto = []
for ( let i = 0; i < 6; i++){
let num = Math.floor(Math.random() * 45 +1)
for (let j in randomLotto){
while(num == randomLotto[j]){
num = Math.floor(Math.random() * 45+1)
}
}
randomLotto.push(num)
}
randomLotto.sort(function(a,b){
return a - b
})
const numClassName = []
for(let i = 0; i < randomLotto.length; i++){
let j = getClassName(randomLotto[i])
numClassName.push(j)
}
for(let i= 0; i <LottoBox.length; i++){
LottoBox[i].innerHTML = randomLotto[i]
LottoBox[i].className = numClassName[i]
}
LottoDisplay.style = 'Display:flex;'
Info.style = 'display:block;'
Payinfo.style = 'Display:block;'
function between(num, min, max){
if(num > min && num < max){
return true
}
return false
}
function getClassName(num){
if(between(num,0,11)){
return 'a'
}
if(between(num,10,21)){
return 'b'
}
if(between(num,20,31)){
return 'c'
}
if(between(num,30,41)){
return 'd'
}
if(between(num,40,46)){
return 'e'
}
}
}
btn.addEventListener ('click',lottoHandler)
작성된 코드가 조금 길기는...합니다.
하지만 이것이 결고 길다고 할 수 있는 것은 아니기때문에, 이를 예시로 설명해보겠습니다.
먼저 이벤트를 부여하기 위해, btn 이라는 변수를 선언합니다.
변수안에는 ID 속성에 'btn' 이라는 명칭을 부여받은 HTML Element 가 있습니다.
이제 이Element 에 이벤트를 부여하기 위해 Method 를 작성합니다. 여기서 들어가는 매개변수는 총 3가지가 있습니다만, 실제 작성은 대부분 2개의 매개변수가 들어값니다.
- 첫번째 매개변수 - Event 명
- 두번째 매개변수 - 함수
- 세번째 매개변수 - 이벤트의 특징을 지정할 수 있음 ( 추후 포스팅예정)
이 addEventListener 는, 반대로 Event 를 제거할수도, 멈출수도 있습니다.
당연히 제거의 경우, 문법에서 "add" 를 "remove" 로 변경하여 removeEventListene 라는 명칠으로 사용하게 되고, 매개변수 역시 동일하게 작성하면 됩니다.
3. 예제 작성해보기
이전 포스팅에서도 먼저 작성해두었던, 예제인 Lotto 에서 사용한 addEventListener 를 이용해서 설명하도록 하겠습니다.
이미 변수 선언등은 이전 포스팅에서 상세하게 다루었으니, EventListner 위주로 설명드리도록 하겠습니다.
먼저 "addEventListener" 를 선언합니다, 매개변수에는 두개의 값이 대입되어야 합니다.
여기서는 "Click", 즉 버튼을 클릭해야 이벤트가 실행되도록 하는 매개변수를 부여합니다. 그리고 실행되는 함수는 "lottoHandler" 라는 함수를 부여했습니다.
여기서 "Click" 에 대입되는 어떠한 동작을해야 이벤트가 실행되는지를 결정되는 여러가지 매개변수가 있습니다.
몇가지 대표적인 것을 정리해보았습니다.
명칭 | 설명 | 작성예제 |
Click | 버튼을 클릭하는 시점에 이벤트가 발생합니다. | addEventListener('click',handler) |
mouseover | 마우스커서를HTML 요소에 올리면 이벤트가 발생합니다. | addEventListener('mouseover',handler) |
moseout | 마우스커서를HTML 요소에 밖으로 이동하면 이벤트가 발생합니다. | addEventListener('mouseout,handler) |
focus | HTML 요소에서 포커스가 되었을때 이벤트가 발생합니다. | addEventListener('focus',handler) |
blur | HTML 요소에서 포커스에서 벗어났을때 이벤트가 발생합니다. | addEventListener('blur',handler) |
keyup | 키를 눌렀다가 떼는 순간 이벤트가 발생합니다. | addEventListener('keyup',handler) |
keydown | 키를 누르는 순간 이벤트가 발생합니다. | addEventListener('keydown',handler) |
resize | 브라우저 창의 크기를 조정하는 순간 이벤트가 발생합니다. | addEventListener('resize',handler) |
scroll | 페이지에서 스크롤바를 드래그하거나, 키보드에서 위아래 버튼을 이용하여 HTML 문서를 스크롤할때 발생합니다. | addEventListener('scroll',handler) |
unload | 링크를 클릭해서 다른 페이지로 이동 혹은 탭을 닫을때, 창을 닫을때 이벤트가 발생합니다. | addEventListener('unload',handler) |
change | 폼 필드의 상태가 변경되었을때 이벤트가 발생합니다. 예를 들면, 라디오 버튼을 클릭하거나, Select Element 를 사용한 리스트에서 값을 선택할 때 발생합니다. | addEventListener('change',handler) |
이외에도 여러가지가 있을 수 있습니다.
여기서 정리한것은 대부분 많이 쓰는 것들이고, 위의 목록외에도 다양한 이벤트 요소가 있으니 필요하신 용도를 확인하시는게 가장 좋을 것으로 생각됩니다.
예제에서 아래와 같이 이벤트리스너를 사용해 이벤트를 추가했습니다. 즉, 여기서는 btn 이라는 변수를 선언하고, 이 변수에 대해 이벤트를 부여한 것입니다. 변수에는 이미, "querySelector" 를 이용해서 HTML Element 를 선택해두었습니다.
const btn = document.querySelector('#submit')
btn.addEventListener ('click',lottoHandler)
이제 이벤트의 함수가 어떻게 동작하도록 할지를 작성했습니다.
먼저 함수의 포함된 작성내용을 다시 보도록 하겠습니다.
function lottoHandler(e){
const randomLotto = []
for ( let i = 0; i < 6; i++){
let num = Math.floor(Math.random() * 45 +1)
for (let j in randomLotto){
while(num == randomLotto[j]){
num = Math.floor(Math.random() * 45+1)
}
}
randomLotto.push(num)
}
randomLotto.sort(function(a,b){
return a - b
})
const numClassName = []
for(let i = 0; i < randomLotto.length; i++){
let j = getClassName(randomLotto[i])
numClassName.push(j)
}
for(let i= 0; i <LottoBox.length; i++){
LottoBox[i].innerHTML = randomLotto[i]
LottoBox[i].className = numClassName[i]
}
LottoDisplay.style = 'Display:flex;'
Info.style = 'display:block;'
Payinfo.style = 'Display:block;'
function between(num, min, max){
if(num > min && num < max){
return true
}
return false
}
function getClassName(num){
if(between(num,0,11)){
return 'a'
}
if(between(num,10,21)){
return 'b'
}
if(between(num,20,31)){
return 'c'
}
if(between(num,30,41)){
return 'd'
}
if(between(num,40,46)){
return 'e'
}
}
}
appEventListener 를 사용하면 "lottohandler" 라는 함수에 많은 내용을 담을 수 있습니다.
하지만 위의 2개의 다른 이벤트생성을 부여하기 위해서는, 이를 각각 하나하나씩 지정해야하고, 그에 맞추어 HTML/CSS 작성도 해야하기 때문에, 여간 불편한 것이 아닐 겁니다. 구현이 불가한 것도 있을 테고요.
이것이 appEventListener 를 사용하는 이유라고 보셔도 무방할 것입니다.
먼저 "function lottohandler(){}" 를 사용해서 함수를 선언합니다. 여기서 ()에 들어갈 매개변수는 꼭 지정되어야 합니다.
하지만 이렇게 appEventListener 에서 발동하는 함수에는 대부분 가독성 및 코드의 확인을 위해서, 매개변수에는 "event", "e" 와 같이 연관된 텍스트를 입력하는 것이 일반적입니다.
예제에서는 "event" 의 약어로 "e" 를 입력하였습니다.
이제 이벤트 안에 담겨있는 함수들을 하나씩 살펴보면 아래와 같습니다.
1. 랜덤번호 생성을 위한 빈 배열 선언 및 반복문을 이용해 중복값이 나타나지 않는 1~45의 무작위 숫자가 오름차순으로 정렬된 함수
const randomLotto = []
for ( let i = 0; i < 6; i++){
let num = Math.floor(Math.random() * 45 +1)
for (let j in randomLotto){
while(num == randomLotto[j]){
num = Math.floor(Math.random() * 45+1)
}
}
randomLotto.push(num)
}
randomLotto.sort(function(a,b){
return a - b
})
2. 랜덤번호의 Array(배열) 과 반복문을 사용해서 전역변수로 이미 선언해둔 HTML Element 에 InnerHTML / ClassName 부여하기
const numClassName = []
for(let i = 0; i < randomLotto.length; i++){
let j = getClassName(randomLotto[i])
numClassName.push(j)
}
for(let i= 0; i <LottoBox.length; i++){
LottoBox[i].innerHTML = randomLotto[i]
LottoBox[i].className = numClassName[i]
}
3. 이벤트를 발동할 때, CSS 에서 Display:none 으로 숨김처리 한 컨텐츠가 표시되도록 변경하기
LottoDisplay.style = 'Display:flex;'
Info.style = 'display:block;'
Payinfo.style = 'Display:block;'
4. 1번에서 추출한 랜덤 숫자의 각 범위별로 그룹을 설정하여, 범위에 해당하는 클래스 이름을 받을 수 있도록 조건문부여
function between(num, min, max){
if(num > min && num < max){
return true
}
return false
}
function getClassName(num){
if(between(num,0,11)){
return 'a'
}
if(between(num,10,21)){
return 'b'
}
if(between(num,20,31)){
return 'c'
}
if(between(num,30,41)){
return 'd'
}
if(between(num,40,46)){
return 'e'
}
}
appEventListener 기능을 이용하면, 하나의 이벤트에 다양한 함수 및 조건문, 반복문등을 이용해서 작성자가 원하는 방향으로 동작하도록 설계가 가능합니다.
하지만 이 기능의 핵심은 작성자가 얼마나 기초적으로 함수를 이해하고 다룰 수 있는 지에 대해서도 중요하게 작용한다고 할 수 있습니다.
문의사항이 있다면 댓글로 문의주시면 감사하겠습니다.
다음 포스팅에서 찾아뵙도록 하겠습니다.
감사합니다.
'개발공부일지 > JavaScript' 카테고리의 다른 글
JavaScript - 삼항연산자에 대하여 (0) | 2022.11.14 |
---|---|
JavaScript - Callback 함수와 동기/비동기 (0) | 2022.11.11 |
JavaScript 실습예제 - Lotto JavaScript 코드 효율화 (0) | 2022.11.10 |
JavaScript 실습예제 - Lotto 번호 생생 웹 페이지 만들기 (0) | 2022.11.10 |
JavaScript - Math 이해하기 (0) | 2022.11.09 |
댓글