> 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)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hidaehyunlee.gitbook.io/fork-my-brain/web/javascript/click-enter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
