keydown과 keyup의 차이를 조심하십시오! IME 입력시 순서가 다르다!

소개



프런트 엔드 개발하고 있으면, 일본어 입력 확정시의 Enter 키가, 확정시의 Enter 키 타열쇠와 판별이 없이 갱신되어 버리는 사건에 고민하는 것은 누구나 조우한 적이 있는 것이라고 생각합니다.


↑↑예)조사라고 하는 문자를 치고, 한자 변환을 확정 Enter를 누르면 그대로 갱신이 되어 버린다

그런 때는 composition 이벤트 을 이용하면 됩니다만, 불가해한 사건에 조금 빠져 버려 몇 시간 녹아 버렸습니다.

같은 사건으로 빠지는 사람이 줄어 들도록

composition 이벤트 사용법



일반적으로 아래와 같이 datacomposing 와 같은 변수를 준비하고, compositionstart , compositionend 로 각각 composing 를 갱신하는 것으로, 상태를 체크할 수 있다고 생각합니다 .

vue.js
<template>
  ...
  <input
    v-model="name"
    type="text"
    @compositionstart="composing = true"
    @compositionend="composing = false"
    @keyup.enter="onChangeName"
  >
  ...
</template>

<script>
export default {
  data() {
    return {
      composing: false // IME入力中かどうか
    }
  },
  methods: {
    onChangeName () {
      if(this.composing) return
      // 更新処理を書く
    }
  }
}
<script>
...

(평상시는 TS 넣고 있습니다만, 알기 쉽도록 생략)

그리고 위와 같이 methodsthis.composing 를 판정해 후속 처리를 멈추거나 합니다. 이것으로 일본어 입력 확정시에 갱신 처리를 실행하지 않게 합니다.

그러나 문제는 일어났다.



위와 같이 하고 있었고, 문제 없게 composing 값도 갱신되어 문제 없었습니다만, 아? 일본어 입력 확정시에도 갱신 처리가 달려 버린다? ! 라는 상황에 조우한 것이 이번 케이스입니다.

시험에 console을 넣어 개발자 툴을 보면, "composing값이 먼저 끝나고, 갱신 처리시의 판정시에는 사용할 수 없다!?"상태가 되고 있었던 것이었습니다.

vue.js
// 省略

<script>
export default {
  data() {
    return {
      composing: false
    }
  },
  watch: {
    composing(val) {
      console.info(val, 'watch') // ←追加!
    }
  }
  methods: {
    onChangeName () {
      console.info(val, 'methods') // ←追加!
      if(this.composing) return
      // 更新処理を書く
    }
  }
}
<script>
...



벌써 발광입니다.

어떻게 하면 좋을까?



결론에서 가면 메소드를 호출하는 keyup 이벤트를 keydown 이벤트로 변경하십시오.

vue.js
<template>
  ...
  <input
    v-model="name"
    type="text"
    @compositionstart="composing = true"
    @compositionend="composing = false"
    @keydown.enter="onChangeName" // ←keyupからkeydownに変更
  >
  ...
</template>
// 省略



그렇게 하면 훌륭하게, methods 에서의 판정 개소에서 composingfalse 가 되는 개소가 나중에 되어 줍니다

왜 keydown으로 피할 수 있을까?


keydown 이벤트는 말 그대로 키를 누르면 발화하고 keyup 이벤트는 키를 눌러 말할 때 발화합니다. 이번에 이벤트를 피할 수 있었기 때문에 keyup 이벤트는 compositionend와 동시에 호출하면 compositionend가 우선되는 것을 알았습니다. 또, keydown 를 이용하는 것으로 명시적으로 compositionend 이벤트보다 먼저 발화시킬 수 있는 것이라고 생각합니다.

사이고에게


keyCode 프로퍼티나 keyPress 이벤트가 Deprecated가 되어 가므로, 일본어 IME 입력시에는 composition 이벤트를 이용해 가게 된다고 생각합니다만, 이런 경우도 있으므로 주의해 주세요~

조금 막힌 재료는 기사로 해 가고 싶습니다!

좋은 웹페이지 즐겨찾기