DOM的.contains(target)与target.contains()的区别及菜单点击场景疑问
二者核心区别
首先明确DOM API Node.contains()的作用:接收一个节点作为入参,返回布尔值,表示传入的节点是否为当前节点的后代节点(包含节点自身),两种写法的判断逻辑完全相反:
- 第一段代码
menuContain.contains(e.target):校验点击目标元素是否属于菜单容器menuContain的内部元素(包括菜单容器本身),返回true说明点击发生在菜单区域内,反之是点击了菜单外。 - 第二段代码
e.target.contains(menuContain):反过来校验菜单容器menuContain是否属于点击目标元素的内部元素,返回true说明点击的元素是菜单容器的祖先节点,能够包裹住整个菜单。
当前场景表现一致的原因
这和你绑定事件的元素、DOM层级结构直接相关:
你将点击事件绑定在了menuFixBg元素上,而你的DOM层级为menuFixBg → menuContain → 菜单内部元素,同时打开菜单时会给menuFixBg设置全屏宽高作为蒙层,所以点击事件触发时,e.target只会出现两种情况:
- 点击在菜单内部:
e.target是菜单内部的子元素,此时menuContain.contains(e.target)返回true,走蓝色分支;而菜单子元素不可能包含作为祖先的menuContain,所以e.target.contains(menuContain)返回false,也走蓝色分支,结果一致。 - 点击在菜单外部:此时点击的就是全屏蒙层
menuFixBg本身,menuContain.contains(e.target)返回false(菜单容器不可能包含它的父元素蒙层),走红色分支;而menuFixBg本身就是menuContain的直接父元素,所以e.target.contains(menuContain)返回true,也走红色分支,结果一致。
如果换个场景,比如你把点击事件绑定在document上,点击页面中其他和菜单无关的元素时,两段代码的执行结果就会完全不同,第二段逻辑会直接出现错误。
内容的提问来源于stack exchange,提问作者Yupma
相关产品推荐
相关产品推荐

