前端最难受的就是产品给的需求和测试给的bug。这个标题是不是有点乱?它是什么?需求,我们往下看吧!需求:如下图,点击保存按钮,弹出保存列表。当你点击屏幕其他区域关闭下拉框时,添加东西是不是很方便,但是点击下拉框里面的区域不能关闭下拉框)(见谅不写东西,就把它当作东西,给它一个机会!),这不是很常见吗,是不是很恶心!你们是怎么做到的。之前看到有人在window上挂事件,然后把class挂在自己不想操作的dom上,然后在click事件中把括号一一排除掉,或者有人投机取巧的把事件挂在partofdom,结果就是测试不是每次都可以关闭,全靠运气!第二天再说说我的解决方案,因为我是写react的,直接上传react代码,逻辑一样,没问题!mount事件首先在componentDidMount中写入我们函数的trigger:window.addEventListener('click',(event)=>{event=event||window.event;this.setState({savedListShow:false,//thisisControl列表的显示和隐藏状态});})事件挂在window上时,如何防止点击列表内部的dom触发?不要说什么以防止冒泡。看看是什么!元素不想触发的识别类是我点击列表输出的事件。说到路径,其实js对象是再一步输出的。既然是js对象,我们就可以拿到对象上的calss属性,我们判断也不是问题。去代码中找到我们不想触发的(或一堆)我们不想触发的dom的最大父级。对了,这里是class为SavedList的div,添加一个class_&saveBtn(别人没有用到,以免冲突)。给点击事件加上判断,排除不想触发的dom。仔细看看我点击输出时的路径,以及每个元素。最后是班级。注意横线上的class,意思是我点击的事件源是我不想要触发的区域,然后我们回到原来componentDidMount中的事件函数。componentDidMount(){//点击其他区域关闭保存条件弹窗window.addEventListener('click',(event)=>{event=event||window.event;letisSaveStructure=event.path.some(item=>{这里使用了StartsWith,比较严谨if(item.className&&typeofitem.className==='string'&&(item.className.startsWith('_&saveBtn')||item.className.indexOf('_&saveBtn')!==-1)){returntrue;}});if(!isSaveStructure){this.setState({savedListShow:false});}})}这取决于dom和我们在dom中的元素不想触发。当遇到这个点击事件时,就会排除掉。是不是很着急?综上所述,添加事件window.addEventListener('click',(event)=>{});在不想触发的dom的最大父级上添加class区分,比如divwithclassSavedList和不需要触发的internaldom在SavedList上添加需要识别的class即可,主要是为了避免和其他人发生冲突,最好是特别的;在之前写的练习中,判断并注意路径是一个数组,里面包含js对象,抓取返回的className是字符串类型,不是数组。我们判断使用startsWith();
