元素用户界面中元素滚动时埃尔选项超出元素区域的问题
复现场景,看图
分析原因
为简单起见,把选项区域描述为波普勒
波普勒的z指数比较大,会覆盖在其他元素上面波普勒默认是插入身体元素的(可以将波普附加到正文设为错误的后不插入到身体)波普勒是在鼠标向上事件里去做隐藏逻辑的,而按下鼠标,移动滚动条的时候,并没有触发鼠标向上事件。波普勒并没有监听滚动事件(没法监听,也没必要监听)解决方案
方案一
我最初想到的解决方案是通过钢性铸铁解决,通过波普级属性给挑选下拉框添加类名,然后用钢性铸铁来做,试了一下这个方案并不可行(只能在某些特定的场景下起作用),遂放弃,可能最优雅最高性能的方法就是用钢性铸铁来搞定,有踩过这个坑的朋友请指点一下
方案二
通过监听$root的卷起事件,利用事件冒泡,只需要在根元素上添加卷起事件的监听就可以了,测试一番之后,发现卷起事件根本不支持冒泡,事件。气泡为假的).
方案三
通过查看元素用户界面的select.vue,发现控制波普勒显隐的是看得见的和emptyText这两个实例属性,很明显,emptytext是不能动的,只能在看得见的上动手脚了。这里放一小段源码
过渡名称=' El-zoom-in-top ' @ before-enter=' handleMenuEnter ' @ before-leave=' doDestroy ' El-select-menu ref=' popper ' : append-to body=' popperappendto body ' v-show='可见空文本!==false' el-scrollbar标签=' ul ' wrap-class=' El-select-down _ _ wrap ' view-class=' El-select-down _ _ list ' ref='滚动条' : class=' { ' is-empty ' :允许创建查询filteredoptions s count===0 }“v-show=”选项。长度0!正在加载el-option :value='query '已创建v-if=' show new option '/El-option slot/slot/El-滚动条p class=' El-select-down _ _ empty ' v-if='空文本(!允许创建| |加载| |(允许创建选项。length===0))' { { emptyText } }/p/El-select-menu/transition全局搜索这个。看得见,发现了这个方法
handleClose(){ this。可见=假;},这下好办了,按图索骥,顺藤摸瓜,找到这个
模板div class=' El-select ' : class='[SelectSize?'El-select-' SelectSize : ' ']' @单击。stop=' toggleMenu ' v-click out=' handleClose '后面的省略.找到点击退出指令之后,豁然开朗原来点击其他区域的时候波普勒会自动关闭的奥秘在这里,结合方案二的灵感,现给出如下代码。
//src/mixins/fackclickouter。jslet锁=真;设El=null const MouseDownEvent=new Event(' MouseDown ',{ bubble : true });const MouseupEvent=new Event(' Mouseup ',{ bubble : true });const fakeclickouter=()={ document。dispatchevent(MouseDownEvent);文件。dispatchevent(MouseupEvent);lock=true//控制台。日志(' dispatchEvent ');};const MouseDownHandle=e={ let class list=e . target。班级名单;if(CLaSS LiST。包含(' El-select _ _插入符号)| | CLaSS LiST。包含(' El-input _ _ inner '){ lock=false;返回;}如果(锁定)返回;fakeclickouter };const MouseWheelHandle=e={ if(lock | | e . target。班级名单。包含(' El-select-down _ _ item ')| | e . target。Parentnode。班级名单。包含(‘El-select-下拉_ _ item’)返回;fakeclickouter };const eventListener=(类型)={ El[键入' event listener ']('鼠标按下,鼠标按下手柄);窗口[类型EventListener']('mousewheel ',mouse wheel handle);窗口[键入事件侦听器'](' domousescroll ',MouseWheelHandle);//FireFox 3.5 }导出默认{ mounted() { el=this .$root .$ elEl。addfakeclickoutedeventcount=El。addfakeclickoutedeventcount | | 0;(!el.addFakeClickOutSideEventCount)这一点$ nextTick(()={事件侦听器(' add ');});埃尔。addfakeclickoutedeventcount=1;},销毁(){事件侦听器(' remove ');埃尔。addfakeclickoutedeventcount-=1;},}使用姿势
建议在根组件上混合,当然也可以在需要的组件上混合(不太推荐,这个代码性能损失应该不大,哈哈哈)
//src/app.vue从' @/mixin/fakeclickouter . js '导入fakeclickouter导出默认{name:' app ',mixin 3360[fakeclickouter],}测试
通用基本用法和自定义模板用法(模板中没有嵌套标记)都可以完美地通过。
如果自定义模板中嵌套了多级标签,则需要向标签中添加标签,然后确定mousewheel事件回调中是否有这样的标签。
摘要
仍然存在的问题(隐患):
mousewheel事件回调中没有节流,考虑到有锁,roller事件的触发频率不是很高(相比mousemove事件),所以没有节流(主要是偷懒)。在mousewheel事件回调中,判断event.target是否在popperEl元素内部的方法不太可靠。而且效率不高,判断是否是mousedown事件中的el-select元素的方法也有同样的隐患,以后再尝试修改(修改不可能也不是不可能)。在自定义模板的使用中,如果有嵌套的标签,那么判断mousewheel事件回调中的event.target是否在popperEl元素内部的方法就会崩溃(这是一个惊雷)。目前的解决方案是手工给嵌套的标签添加一个标签,在事件中添加这个标签的判断,但是这个方法对于已经写好的模板是无效的,只能再次修改。已经考虑了递归向上搜索。但是效率不高,性能消耗太高,定制的el-option模板在我们目前的业务中几乎不存在,所以没有考虑这个bug。感谢一位大哥的长期帮助。
版权声明:元素用户界面中元素滚动时埃尔选项超出元素区域的问题是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。