자바스크립트 #03 콜백, 이벤트리스너 , 비동기

수박·2020년 6월 10일
0

JavaScript

목록 보기
3/22

자바스크립트 #03 콜백, 이벤트리스너 , 비동기

콜백함수

특정한 시점에 호출되는 함수


이벤트리스너(핸들러)

이벤트가 발생했을 때 그 처리를 담당하는 함수

객체나 요소에 등록되어야만 호출이 가능하다.

이벤트 리스너 등록방법은 두가지가 있다.

  1. 객체, 요소에 프로퍼티로 등록
  2. 객체, 요소의 메소드에 이벤트리스너를 전달

프로퍼티 등록은 다음과 같다.

window.onload = function() {                   var text = document.getElementById("text"); // 아이디가 "text"인 요소를 선택함.
text.innerHTML = "HTML 문서가 로드되었습니다.";

}

이벤트 타입별로 오직 하나의 리스너만 등록할 수 있다.

이벤트리스너 전달을 하기위해서 다음 메소드를 사용한다.

대상객체.addEventListener(이벤트 명, 실행할 이벤트 리스너, 이벤트 전파방식)

이벤트 전파방식은 false면 버블링방식, true이면 캡쳐링방식으로 이벤트를 전파한다.

버블링? 캡쳐링? 뭘까?

버블링, 캡쳐링방식

DOM트리에 따라 이벤트를 전파하는 방식이다.

DOM은 트리형태로 부모, 자식간의 관계를 갖는다. 이벤트 리스너도 트리의 속성을 따른다.

버블링방식
  • 어떤 요소의 리스너가 실행되면 부모요소의 리스너도 실행된다. 이것이 버블링 전파방식이다.
function clickDiv(event)  { document.getElementById("text").innerHTML += "div 요소를 click 하셨네요!<br>"; }

function clickPara(event) { document.getElementById("text").innerHTML += "p 요소를 click 하셨네요!<br>"; }

function clickSpan(event) { document.getElementById("text").innerHTML += "span 요소를 click 하셨네요!<br>"; }

현재 div하위에 p요소, p 안에 span요소가 존재한다.

div- p - span형태로 존재하는데, span을 누르면 span, p, div를 호출하고, p를 누르면 p, div를 호출한다. 이렇게 자식에서 부모쪽으로 이벤트를 전파시킨다.

캡쳐링방식
  • DOM트리의 최상위부터 아래로 내려가는 전파방식이다.

버블링방식은 아래에서 위로 전달되는 방식이라면 캡쳐링은 그 반대이다.

span요소를 클릭하면 div-p-span순으로 호출한다.

p요소를 클릭하면 div-p순으로 호출한다.

이벤트리스너를 등록하는 방법을 사용하면 여러개의 리스너를 등록할 수 있다.

btn.addEventListener("click", clickBtn);         // 선택한 요소에 click 이벤트 리스너를 등록함.

btn.addEventListener("mouseover", mouseoverBtn); // 선택한 요소에 mouseover 이벤트 리스너를 등록함.

btn.addEventListener("mouseout", mouseoutBtn);   // 선택한 요소에 mouseout 이벤트 리스너를 등록함

이벤트 리스너를 삭제할 수도 있다.

    btn.removeEventListener("mouseout", mouseoutBtn);

야구게임

야구게임

1~9까지의 4개의 숫자가 랜덤하게 선언된다.

플레이어는 4개의 숫자를 모두 맞추어야한다.

매 턴마다 플레이어는 4개의 숫자를 제출하고 해당 숫자가 맞는지 검사한다.

ball, strike으로 힌트를 받을 수 있다.

ball은 플레이어가 제시한 숫자중 랜덤숫자가 포함되어있고 위치가 다른경우.

strike는 숫자, 위치 모두 맞는 경우이다.

ex)

랜덤숫자 2,4,8,6

플레이어 제출 답 1,2,4,6일 때 4는 맞지만 위치가 다르므로 4는 1ball, 6은 위치, 숫자모두 맞으므로 1strike이다.

결과

코드


var body = document.body;
var numCandidate = new Array(9); //숫자 후보군 배열
var numArr = new Array(4); //뽑힌 숫자 배열

var ul = document.createElement('ul');
document.body.append(ul);
ul.style.listStyle="none";

var form = document.createElement('form');
document.body.append(form);

var input = document.createElement('input');
form.append(input);

var button = document.createElement('button');
form.append(button);
button.textContent = "submit";

//초기 실행 함수


//후보군 생성기
function generateCandidate(){
    var max = 9;
    for(var i = 0 ; i < max; i++)
        numCandidate[i] = i + 1;
}

//후보군에서 숫자 뽑기
function generateNum()
{
    for(var i = 0; i < 4; i++)
        numArr[i] = numCandidate.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
    document.write(numArr);
}
function init(){
    generateCandidate();
    generateNum();
}

init();
//Ball Check function
function checkBall(answer){
    var arrLenght = answer.length;
    var ballCnt = 0;
    for(var i = 0 ; i < arrLenght; i++)
    {
        for(var j = 0; j < numArr.length; j++)
        {
            if(answer[i] == numArr[j])
                ballCnt++;
        }
    }
    return (ballCnt);
}

function checkBallStrikeCnt(answer){
    var idx = answer.length;
    var matchCnt = [0,0];
    while(idx-- > 0)
    {
        if(Number(answer[idx]) === numArr[idx])
            matchCnt[0]++;
        else if(numArr.indexOf(Number(answer[idx])) > -1)
            matchCnt[1]++;
    }
   
    
    return (matchCnt);
}

//Input data check vaildation
function dataVerfiy(arrLenght, answer){
    if(arrLenght != 4)
    {
        alert("4글자의 숫자를 입력해주세요.");
        return (-1);
    }
    return (1);
}

function printAnswer(matchCnt, answer){
    var li =document.createElement('li');
    
    ul.appendChild(li);
    li.textContent = answer + " : "+ matchCnt[0]+" 스트라이크 "+matchCnt[1]+" 볼입니다. ";
    if(matchCnt[0] == 4)
        alert("홈런");
}

form.addEventListener('submit', function(e){
    e.preventDefault();
    //길이가 1인 스트링배열을 가지는 객체 answer
    var answer = input.value.split('');
    var arrLenght = answer.length;

    console.log(answer);
    
    console.log(arrLenght);
    if(dataVerfiy(arrLenght, answer) < 0)
        return ;
    var matchCnt = checkBallStrikeCnt(answer);
    printAnswer(matchCnt, answer);
});

0개의 댓글