今天还是分享一道我亲身经历的面试题,真的是基础中的基础了,关于JS事件的。先唠叨点题外话:面试机会是朋友内推帮我挣来的,好不容易有个面试,还是个高级工程师的岗位,所以也比较重视。然后我就去看了他们的JD,仔细把上面的每一条都准备了下,上面还有架构相关的内容,我就也临时抱佛脚的做了一些架构,工程化相关的准备。结果有点出乎意料,一点工程化相关的都没有问,架构流程相关的也没,都是问些基础或者原理性的东西,有的我甚至觉得有点偏了(可能是我太菜不知道吧)。不过其中有个问题我觉得挺好,印象挺深刻的,真的能反映出一个人的前端基础是否扎实,所以记录下来分享一下。
面试官问:页面有两个 input 框 A 和 B,一开始鼠标聚焦在 A,然后点击 B,此时 B 框聚焦。整个过程发生了哪些事件。
我第一反应是有个聚焦和失焦事件,然后有个点击事件,所以顺口就说了出来这三个。面试官不太满意,追问还有其它事件吗?我想了想说还有个press事件和一个鼠标抬起事件,当时有点懵了,本来想说的是mousedown和mouseup,当时硬是没想起来。然后面试官就追问:那它们的执行顺序怎么样的? 我就不知道了,清晰的记得当时回答的原话是:’事件流的事件捕获,事件处理和事件冒泡倒是有了解,这几个事件的执行顺序我没研究过‘。现在回想起来自己是真的菜啊,这种基础问题都答不上来,基础太差,而且回答的都是啥啊,牛头不对马嘴的。
痛定思痛,下来赶紧恶补相关的知识,以下应该是面试官想听到的答案:
mousedown:当用户点击鼠标按钮时,首先触发mousedown事件。这是因为动作的物理部分(即按下鼠标按钮)是交互的开始。focusout/blur:当用户从一个输入框(a)点击到另一个输入框(b)时,a将失去焦点。在某些元素失去焦点时,浏览器会触发focusout或blur事件。这些事件发生在mousedown之后,因为焦点的改变通常是由鼠标的点击行为导致的。focusin/focus:在新元素(b)上触发focusin或focus事件,表示它现在获得了焦点。这个事件在focusout/blur之后发生,因为浏览器先处理旧元素失去焦点的事件,然后再处理新元素获得焦点的事件。mouseup:用户在b上释放鼠标按钮时,触发mouseup事件。mouseup事件发生在focusin/focus之后,因为用户需要在新元素上释放鼠标按钮来完成点击动作。click:最后,当mousedown和mouseup事件在同一个元素上连续发生时,触发click事件。click事件是对整个点击动作的确认,只有在mouseup事件之后才能确定点击动作已经完成。
注意
mousedown和mouseup是鼠标事件,而focusout、blur、focusin和focus是焦点事件。blur和focus事件不冒泡,但是它们对应的冒泡版本是focusout和focusin。- 焦点事件通常在鼠标事件之间触发,因为鼠标操作会导致焦点的变更。
mousedown和mouseup事件在同一个元素上连续发生时,触发click事件
结语
其实所谓高级工程师,我觉得他不仅熟悉/精通各种上层应用或框架,底层的基础更要扎实,万丈高楼平地起,基础真的很重要。就比如鼠标事件都有很多,这里只是其中一部分,还有以下这些,那你是否都掌握了呢?
dblclick: 当在同一个元素上连续两次点击时触发。mousemove: 当鼠标指针移动时触发,无论是否按下鼠标按钮。mouseover: 当鼠标指针移入元素或其子元素时触发。mouseout: 当鼠标指针移出元素或其子元素时触发。mouseenter: 当鼠标指针移入元素时触发,不冒泡,且没有移入子元素的触发。mouseleave: 当鼠标指针移出元素时触发,不冒泡,且没有移出子元素的触发。contextmenu: 当尝试打开上下文菜单时触发,通常通过鼠标右键或特定键盘按键。