前言
最近一段时间一直处于不停改Bug的状态(结果是bug越改越多。。),本文分享一下在这期间学到的一些新的知识。
scroll
下面来看一个dom结构
<div id="parent">
<Modal>
</div>
下面简单描述一下这个和scroll
事件有关的bug的场景。
父元素parent是一个块级元素,在其上面绑定scroll
事件,随着鼠标滑轮的滚动,parent的UI会发生变化。
子元素是一个Modal
组件,有自己的逻辑。现在发生了一个问题,当打开子元素的Modal
弹窗后,对着Modal
内部的元素做了一系列交互之后,发现parent
元素的UI发生了变化,通过debug之后,查出原因,当子元素Modal内部出现滚动条,鼠标滑轮进行滚动,触发了parent
元素的scroll
事件,导致parent
的UI发生了变化。
一般情况下,这种问题我们只要阻止子元素的事件进行冒泡,就可以解决这个问题。但比较特殊的就在于这个scroll
事件。恰好最近听了一位同事的技术分享,讲的就是这个scroll
事件,scroll
事件最特殊的一点在于,它不能阻止事件冒泡,或者说scroll
本身就没有冒泡机制。
由于JS事件的冒泡机制,触发事件的元素会逐渐向上层传递,我们可以在document中收到所有的事件触发。所以当我们的要写一套和js事件相关的库的话,就可以将所有的事件放到最上层的document中进行处理,这种方式叫做事件委托,React的事件就是这么处理的。但是有些事件比较特殊,比如我们这次提到的scroll
,甚至于React对scroll
事件的代理都是放到了捕获阶段。
不知道有没有人发现上述的逻辑似乎有点问题,scroll
比较特殊,他没有冒泡机制,也不能被取消,那么子元素的滚动,其实是不能传到parent
元素的,所以按道理正常情况这个bug是不会产生的。
其实这个bug是很好解决的,我最后是在Modal打开的状态下直接禁用掉了parent
元素的onScroll
方法,但是这种现象值得深挖一下背后的逻辑。
这里我有两种猜测,一是我们系统中使用的是React
的事件体系,并非原生的JS事件,所以导致了这个问题。 二是Modal
组件使用了react-modal
这个库,这个组件比较特殊导致的。
因为时间问题,这两种猜测我没有深入研究,后续有时间会继续跟进。
和scroll
事件类似的还有blur
、focus
等事件
compositionstar
和 compositionend
这两个事件如果了解过JS监听中文输入法这方面知识的程序员可能知道。
先来一段MDN的定义
文本合成系统如 input method editor(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。
当文本段落的组成完成或取消时, compositionend 事件将被触发 (具有特殊字符的触发, 需要一系列键和其他输入, 如语音识别或移动中的字词建议)。
简单来说,就是使用中文输入法的时候,当开始输入汉字时触发 compositionstar
,当输入完成时触发compositionend
,可以不管这期间用户输入多少个拼音。
这两个事件本身没什么好说的,用到的可以搭配input
或者change
事件来实现相关业务。
但是最近遇到个比较特殊的使用场景,那就是移动端输入的英文智能联想(我一直是小米手机,从来不知道还有这个功能,听其他人说,大部分手机输入法都是默认开启的)。英文的智能联想开启之后,会导致英文输入变成了中文输入法一样的场景。一般情况下似乎也没什么问题。但是我们项目中使用的draft-js
这个富文本的组件就在英文智能联想的场景中出现了问题。
这个组件的onChange
方法,在英文智能联想输入的情况下,如果将文本全部清空,onChange
方法就不会触发,导致用户无法将自己输入的内容一次性删除。
定位到draft-js
之后,发现最新版本是没有这个bug的,然后开始进行版本升级,这里主要提醒一下,如果有这种对输入文本进行比较复杂的数据处理的功能的话,最好别忘了输入法英文智能联想这个功能。
总结
以上是对工作中遇到的一些知识的总结,希望以后再遇到相同的问题可以及时定位处理。