-
在瀏覽器中,對於input節點的用戶輸入,什麼時候觸發"change"事件呢?
-
在瀏覽器中,JS更新input的value屬性,會觸發"change"事件嗎?
-
若是不會觸發,請問爲何?有什麼辦法解決嗎?
-
當input在用戶輸入後,節點失去焦點的時候觸發」change"事件,而且在「input"事件以後;
-
若是讀者沒理解,能夠看下面的代碼;
結論是:不會觸發」change"事件;
-
目前搜索到的W3C規範中,貌似沒有這樣的能力,包括:"MutationObserver";固然,若是開發者調用dispatchEvent的方式不算;
若是讀者只在意結論的話,就能夠不往下看了;下面聊下W3C的定義;
你們是否好奇:JS更新input的value屬性,爲何不觸發"change"事件呢?
The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus. This attribute applies to the following elements:
INPUT,
SELECT, and
TEXTAREA.
規範說:該事件源於input控件在
用戶操做後失去焦點而且value變化時觸發;
value On getting, return the current value of the element. On setting: 1. Let oldValue be the element's value. 2. Set the element's value to the new value. 3. Set the element's dirty value flag to true. 4. Invoke the value sanitization algorithm, if the element's type attribute's current state defines one. 5. If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the element has a text entry cursor position, move the text entry cursor position to the end of the text control, unselecting any selected text and resetting the selection direction to "none".
能夠看到:其中並無約定要觸發"change"事件;
若是讀者只在意W3C定義的話,就能夠不往下看了;下面聊聊爲何;
你們是否好奇:JS更新input的value屬性,W3C爲何不觸發"change"事件呢?
我以爲"change"事件這麼定義在語義上有問題,若是不想有問題,那麼辦法有兩種:
-
JS更新,觸發」change"事件;
-
將規範中的"change"事件名稱,改名爲:"userchange"或者"uachange";(ua表明user agent)
站在開發者的認知角度上,"change"表明的是一種"狀態"的變化,它不在意是"主動改變"仍是"被動改變";主動爲用戶的輸入改變,被動爲代碼層面的更新賦值;
按照正常人對上面"change"單詞的語義理解,JS更新value,也屬於一種狀態change(更況且UI都會變化),就應該觸發"change"事件纔對;
帶着這個疑問我問了一圈身邊的開發者,有了下面的對話:
做者:問個問題:經過JS修改input的value值,爲何監聽的input,change事件不會觸發呢?爲何這麼設計?
大壯:我理解的change事件應是在value只改變且失去焦點時纔會觸發,應該是從性能上考慮的吧 html
翠花:value的改變是事件觸發的結果,若是變成緣由是否是就死循環了 二壯:應該是避免事件冒泡致使沒必要要的性能損失吧,我猜的html5
W3C:When the change event applies, if the element does not have an activation behavior defined but uses a user interface that involves an explicit commit action, then any time the user commits a change to the element's value or list of selected files, the user agent must queue a task to fire a simple event that bubbles named change at the input element, then broadcast formchange events at the input element's form owner. git
做者:Chrome源碼沒看到線索,查了W3C,我理解這麼個意思: change事件屬於用戶GUI操做產生的,對於經過JS改變的行爲,不屬於這類管理範圍; 做者:我深深以爲這是web的坑,很早這種行爲就定了,又無法兼容。你看Android就不是這種行爲呀。從名字上來講,input事件不觸發合理,change事件名,從直觀理解就應該觸發呀。js更新不算change?github
對話:... 後面又聊到了"event loop"與異步機制,對話走偏了,就不扯了;web
事實上,若是在Android平臺中,經過代碼修改,確實會觸發相似的"textchanged"事件的;
老外2:
Unfortunately, we cannot change the names of events that have been dispatching for over two decades.
事實證實了個人見解,
規範的原始定義形成了既成事實:
若是硬要揪毛病,確實不合適;可是已經定義了20多年了,再改很容易不兼容!
好了,截止這裏就結束了;
之因此問這個問題,是由於快應用在設計的時候,就面臨着:面試
到底遵照W3C規範(不觸發),仍是Android其它平臺(觸發)的行爲;