-
在浏览器中,对于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其它平台(触发)的行为;