> For the complete documentation index, see [llms.txt](https://hidaehyunlee.gitbook.io/fork-my-brain/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hidaehyunlee.gitbook.io/fork-my-brain/web/javascript/click-enter.md).

# Click, Enter 두 개의 이벤트 동시에 등록하기

undefined

**index.html**

```markup
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <h1>끝말잇기 게임</h1>
    </div>
    <div>
        <span>제시어 :  </span>
        <span id="word">한글</span>
    </div>
    <form id="form">
        <input type="text" id="input">
        <button type="submit" id="btn">입력</button>
    </form>
    <div id="result"></div>
    <script src="./index.js"></script>
</body>
</html>
```

**index.js**

```javascript
const form = document.querySelector('#form');

form.addEventListener('submit', (e) => {
    const word = document.querySelector('#word').textContent;
    const input = document.querySelector('#input').value;
    const lastLetter = word.substr(-1);
    const firstLetter = input[0];
    const err = '글자를 입력하세요!'

    if (input){
        if (lastLetter === firstLetter){
            document.querySelector('#word').textContent = input;
            document.querySelector('#result').textContent = '정답!'
            document.querySelector('#input').value = '';
        }
        else {
            document.querySelector('#result').textContent = '땡!'
        }
    }
    else {
        alert(err);
    }
    e.preventDefault();
});
```

#### 고민지점

1. 문자열 마지막 글자 추출하기
2. `enter`키 누르면 입력되는 이벤트 등록하기
3. 하나의 요소에 `click` 과 `enter` 두 개의 이벤트 동시에 등록하기
4. 영어단어 값 랜덤으로 가져오기

## 1. 문자열 마지막 글자 추출하기

방법이 여러가지가 있고, 전부 다 작동하는 걸 확인했다. 나는 가장 간단하고 익숙한 `substr`함수를 사용했다.

#### 1) 배열 인덱스

```javascript
var str = "Test"; 
var lastLetter = str[str.length - 1];
```

그런데 [여기](http://blog.vjeux.com/2009/javascript/dangerous-bracket-notation-for-strings.html)에 따르면 대괄호를 사용하는 건 지원 안되는 브라우저도 있어서 권장되지 않는다고 한다.

#### 2) charAt \[index]

```javascript
var lastLetter = str.charAt(str.length - 1)
```

가장 많이 쓰이고 가장 권장되는 방법이다.

#### 3) 부분 문자열

```javascript
str.substring(str.length - 1);
```

#### 4) slice()

```javascript
const lastLetter = str.slice(-1);
```

#### 5) substr()

```javascript
const lastLetter = word.substr(-1);
```

## 2. `enter` 키 이벤트 등록

### 2.1. 키보드 이벤트

자바스크립트 **키보드이벤트**는 총 3가지가 있다.

| 이벤트명       | 발생하는 시점                  | 값       |
| ---------- | ------------------------ | ------- |
| `keydown`  | 키가 눌렸을 때                 | keycode |
| `keypress` | 키가 눌린 상태일 때(연속적으로 실행됨.). | ASCII   |
| `keyup`    | 키 누름이 해제될 때              | keycode |

* `keypress`  이벤트는 ASCII 표에 없는 `shift`, `Fn`, `CapsLock` 키는 인식하지 못한다.
* keyCode 를 확인할 수 있는 [유용한 사이트](http://keycode.info/)

따라서 아래 두가지 방법 모두 사용가능하다. `keyCode` 와 화살표함수를 사용한 밑에 방법이 좀 더 맘에 든다.

```javascript
document.querySelector('#input').addEventListener('keypress', function (e) {
    if (e.key === 'Enter') {
      // code for enter
    }
});
```

```javascript
document.querySelector('#input').addEventListener('keyup', (e)=>{
    if (e.keyCode === 13) {
        // code for enter
  }  
});
```

처음에는 `click` 이벤트를 만들었을 떄 처럼 `입력` button 태그에 이벤트를 등록해야 될거라고 생각했다. 안되는 게 당연하다. 사실 우리가 보통 로그인할 때를 생각해보면 아이디/비밀번호를 **입력**한다음에 엔터를 누른다.

즉, 키보드이벤트는 사용자로부터 입력받은 값을 `keyCode`에 저장해서, 그게 enter의 키코드 값과 일치하는지 확인하는 것이기 때문에 **`input 태그`에 등록해야한다.**

* [참고](https://stackoverflow.com/questions/14542062/eventlistener-enter-key/50993410)

### 2.2. eventListener 목록

[eventListener type(이벤트 유형) 목록](https://developer.mozilla.org/ko/docs/Web/Events)

## 3. 복수의 이벤트 등록하기

일단 [이 글](https://teamtreehouse.com/community/how-to-add-enter-event-listener-aside-from-clicking-the-button)을 보면 하나의 요소에 여러개의 이벤트리스너를 붙이는 건 상관없는 듯 하다.

```javascript
const input = document.querySelector('#myInput');
input.addEventListener('keyup',function(e){
    if (e.keyCode === 13) {
    alert('hi');
  }  
});

input.addEventListener('click',function(){
  alert('you clicked me!');
});
```

그런데 이렇게 하면 각각의 이벤트에 똑같은 콜백함수를 두 번 써야돼서, 더 좋은 방법이 있을거라고 생각했다. 하나의 이벤트리스너에 논리연산자를 써서 두 가지 타입을 설정한다던지...

그런데 구글링을 해도 내가원하는 답을 찾기 쉽지 않았다. 그래서 아예 다른 방법을 찾았다. form태그에 이벤트를 등록하는 방법이다.

### 3.1. form 태그에 이벤트 등록하기

`form 태그` 내부의 button태그를 `submit` 하면 클릭과 엔터가 동시에 입력된다. 이걸 이용해서 form 태그에 이벤트를 등록하면 클릭을 하든 엔터를 누르든 같은 이벤트로 취급할 수 있다.

#### button submit 리로드 막기

대신, form 태그에 이벤트를 등록할 때 주의할 점이 있다.

form 태그는 기본적으로 `submit`을 실행하고 나면 리로드가 되기 때문에 내부 함수가 실행되지 않는다. 그래서 콜백에서 `e.preventDefauit()`를 써서 **기본동작인 리로드를 막아줘야 한다.**

```javascript
form.addEventListener('submit', (e)=>{
    e.preventDefault();
});
```

## 4. `addEventListener` vs `onclick`

자바스크립트를 공부하기 위해 보는 최신 강의들은 전부 이벤트리스너 방식으로 이벤트를 등록한다. 그런데 구글링을 하다보면 html의 `onclick` 속성을 이용해서 이벤트를 등록하는 방식의 글이 대부분이다.

스택오버플로우에도 이 주제에 대한 [토론](https://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick)이 있는데, 둘 중의 하나가 최신이거나, 권장되거나 하지는 않는 것 같다.

한 요소에 복수의 이벤트를 등록하려면 `addEventListener`를 사용해야하고, HTML에서 인라인으로 이벤트를 바로 넣고싶으면 `onclick`을 사용하면 된다.

## 5. 참고

* [EventTarget.addEventListener() 공식문서](https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener)
* [eventListener type(이벤트 유형) 목록](https://developer.mozilla.org/ko/docs/Web/Events)
* [KetCode 확인 사이트](http://keycode.info/)
* [이벤트리스너와 온클릭](https://c10106.tistory.com/4115)
