When I want to type a Chinese character, such as day , then I have to enter the two letters ri , and in some cases the characters I enter are to have data interaction with the backend, so in some cases I originally just want to communicate with The back-end interaction day is the word, but because the pinyin of day is ri , I may have had two interactions with the back-end when I typed the day , one is r and the other is ri , which obviously does not meet our needs. operation logic;
First, let's look at an excerpt from an article:
Excerpt from segmentfault
The problem and solution of Chinese input method and React text input box The
source of the problem is issue #3926 from this React official repository. There are many other issues related to this issue, from many projects, some are related to React, some are Is vue or other JS suite. There are already other projects focused on solving this problem, such as react-composition, but it is a React component using ES5 syntax. There are similar questions and answers on other forums. The purpose of this article is to hopefully provide some explanatory, now tentative solutions to this problem.
onChange on the browser, as long as there is any keyboard action on this text input box, it will trigger, that is, if you use Chinese, Japanese, Korean input method (IME), no matter which one, Pinyin, Stroke or other, as long as there is an action of pressing a keyboard, the change event of this element on the browser will be triggered once. For languages that originally use English characters on the keyboard as input, this is not a big problem. , but for language users who want to use the input method, constantly triggering the change event may cause problems with the running logic of the program function.
To give an actual application, a function for searching computer books written by React, the user can enter the title of the book to be searched in the text input box, and the program is triggered by the onChange event to compare the title of the book in the database, When you want to search for a book named "Lin Ge's Java Tutorial", the first word is "Lin", the pinyin input method needs to enter "lin" three characters on the keyboard, the word "Lin" is edited from the input method Before adding it to the real input element, onChange has captured the three characters of "lin", and a lot of books about "linux" have been searched in the list. The details will not be said, and there may be issues such as checking the number of characters. However, is this the correct program logic? Obviously this is a big question.
Of course, you can also use the modified method of checking Chinese characters, or simply don't use the change event, and use other events such as button triggers to do
this. This problem has already been dealt with in the browser. The solution, there is a set of additional CompositionEvent (composition events) in the DOM event to assist developers, it can be triggered on editable DOM elements, mainly on input and textarea, so it can be used to assist in solving the input method of the change event question. CompositionEvent (composition event) has three events, namely compositionstart, compositionupdate and compositionend. They represent the beginning of word composition, refresh and end, which means that the input method editor starts to combine English characters on the keyboard. Combination of words or refresh words, and finally output words to the text input box in the real DOM. In practice, when each Chinese character is input, compositionstart and compositionend will only be triggered once, while compositionupdate may be triggered multiple times. trigger.
The solution is to use the assistance of CompositionEvent, that is to say, the input element on the web page can use CompositionEvent as a signal. If you are using IME to input Chinese, the code in the change event should not be run first, and when compositionend is triggered, Then the change event can run the code, and the principle of operation is as simple as that.
This solution works well in almost all browsers (IE9 and above) that can support CompositionEvent, but after version 53 of Google Chrome in 2016, the triggering order of change and compositionend has been changed, so it is necessary to target Adjust the Chrome browser. If the compositionend is triggered in the Chrome browser, the code to be run in the change should also be run once.
Next we come back to the topic
The method mentioned above can solve 90% of pinyin input problems, but recently IOS10.3 was released, so new problems appeared! ios10.3 has adjusted the triggering order of compositionEvent state, which is the same as chrome, that is to say, if the other party uses the system of ios10.3 version, then additional processing must be performed on him, and it will be triggered manually after compositionEnd. A change event. . .
Next, let's sort out the code: (below, we write the code in the way of React ES6, other writing methods are similar, please adjust it yourself)
First browserDetection.js
/** * Created by Luna_Shu on 2017/3/30. * * @author Luna_Shu * @description judge the browser * */ // Opera 8.0+ export const isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; // Firefox 1.0+ export const isFirefox = typeof InstallTrigger !== 'undefined'; // Safari 3.0+ "[object HTMLElementConstructor]" export const isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari . pushNotification ) ; // Is it an IOS system export const isIOS = navigator . userAgent . indexOf ( 'iPhone' ) >= 0 || navigator . userAgent . indexOf ( 'iPad' ) ; // Get the IOS system version export const IOSVer = navigator . userAgent . match ( /\d[\d]*_\d[_\d]*/i ) && parseFloat (navigator.userAgent.match(/\d[\d]*_\d[_\d]*/i)[0].split('_').join('.')); // Internet Explorer 6-11 export const isIE = /*@cc_on!@*/false || !!document.documentMode; // Edge 20+ export const isEdge = !isIE && !!window.StyleMedia; // Chrome 1+ export const isChrome = !!window.chrome; // Blink engine detection export const isBlink = (isChrome || isOpera) && !!window.CSS;