JavaScript中的composition event

最近在閱讀Element-UI的input組件源碼時,發現其使用了composition事件:

<input
  :tabindex="tabindex"
  v-if="type !== 'textarea'"
  class="el-input__inner"
  v-bind="$attrs"
  :type="type"
  :disabled="inputDisabled"
  :readonly="readonly"
  :autocomplete="autoComplete || autocomplete"
  :value="currentValue"
  ref="input"
  @compositionstart="handleComposition"        // 注意這里!
  @compositionupdate="handleComposition"   // 注意這里!
  @compositionend="handleComposition"        // 注意這里!
  @input="handleInput"
  @focus="handleFocus"
  @blur="handleBlur"
  @change="handleChange"
  :aria-label="label"
>

印象里紅皮書好像有提到過,但已經記不清有什么作用了,趁此機會學習下。

composition event,即復合事件,用于處理IME的輸入序列。
IME(Input Method Editor,輸入法編輯器)可以讓用戶輸入在物理鍵盤上找不到的字符。
其實就是我們用中文輸入法時,出現的顯示中文的框:


image.png

composition event包括三個事件:

  • compositonstart: 在IME的文本復合系統打開時觸發,表示要開始輸入例如(輸入法出現的那一刻)
  • compositionupdate: 在向輸入字段中插入新字符時觸發(使用輸入法輸入的過程中)
  • compositionend: 在IME的文本復合系統關閉時觸發,表示返回正常鍵盤輸入狀態(選中文字,輸入法消失的那一刻)

那Element-UI為什么要使用composition event呢?
這其實跟composition event的作用有關,我們來看下compotion event與input event的觸發順序:


image.png

可以看到,首先輸入法出現,觸發了compositonstart事件,然后分別輸入'w'和'o',先是觸發compositionupdate事件,再是觸發input事件。當然,如果選擇了中文,會觸發compositionend事件。
這里的重點是,在拼音還未轉化成中文的時候,同時有兩個輸入框存在:

  • 頁面上的input輸入框
  • 輸入法的輸入框

兩者分別會觸發input和compositionupdate事件。這樣問題就出現了,用過Element-UI或者類似UI庫的同學都知道,input組件多數情況下都是配合著form組件使用的,既然是表單,那也離不開表單驗證了。那么問題就在于,如果是通過input事件來觸發驗證的,輸入的是字符,那倒沒什么問題。可要是輸入的是中文(或者其它需要組合拼出來的語言),比如,要輸入'我',在拼音還沒轉換之前,網頁輸入框中的內容時'wo',也會觸發驗證,這并不是我們想要的!

因此,我們可以使用復合事件,通過一個變量來判斷是否是在composition event中,是,就不去觸發input事件。
當然,Element-UI也是這么做:

handleComposition(event) {
  if (event.type === 'compositionend') {
    this.isOnComposition = false;
    this.currentValue = this.valueBeforeComposition;
    this.valueBeforeComposition = null;
    this.handleInput(event);
  } else {
    const text = event.target.value;
    const lastCharacter = text[text.length - 1] || '';
    this.isOnComposition = !isKorean(lastCharacter);
    if (this.isOnComposition && event.type === 'compositionstart') {
      this.valueBeforeComposition = text;
    }
  }
}

該方法是composition event的統一處理方法,this.isOnComposition用來判是否開啟了輸入法,在compositionend事件觸發時,將this.isOnCompostion = false; 表明輸入法已關閉,再去執行this.handleInput,即input事件的處理方法。

handleInput(event) {
  const value = event.target.value;
  this.setCurrentValue(value);
  if (this.isOnComposition) return;
  this.$emit('input', value);
}

在handleInput方法中,可以看到,若this.isOnComposition為true,是不會執行this.$('input', value);的,即不會向父組件派發input事件,如果父組件是form組件,也就不會去觸發表單驗證了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容

  • Windows 95中文輸入法編輯器(IME) 微軟 翻譯:TBsoft Software Studio ...
    returntrue閱讀 2,711評論 0 3
  • ??JavaScript 與 HTML 之間的交互是通過事件實現的。 ??事件,就是文檔或瀏覽器窗口中發生的一些特...
    霜天曉閱讀 3,526評論 1 11
  • 第13章 事件 1. 事件流 事件流描述的是從頁面中接收事件的順序。 (1) 事件冒泡 IE 的事件流叫做事件冒泡...
    yinxmm閱讀 963評論 0 17
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,830評論 18 139
  • 一直在尋找一個可以隨心交流,抒寫自己故事的地方,這個地方有人傾聽我的故事,有人分享自己的故事,我們就這樣交流著。簡...
    海洋小姐閱讀 370評論 2 0