引言:做可视化地图项目,使用vue-seamless-scroll实现表格数据自动滚动,有个bug就是复制出来的数据点击事件失效。这个插件底层的实现是cope的形式,
无限滚动原理:无限滚动的原理就是把之前的遍历的内容复制一份,滚动这两部分内容,达到无缝滚动效果。(一般数据量比较多有这种效果,数据量比较少,我就不让他滚动了)。
问题分析:
当第一个ul中的数据滚动完时(真实数据),第二个ul 部分的click事件不起作用(复制出来的数据),无法实现一些点击这行,弹窗详情信息业务需要功能。
我需要这些数据添加一些点击事件,弹出二级页面及区域切换效果。
解决办法:
方式一:
采用事件委托的方式:
事件委托又叫事件代理,就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
一般来说,DOM需要有事件处理程序,我们都会直接给它设定事件处理程序就好了,但是如果有很多DOM需要添加处理事件,比如,一个ul下有很多个li,需要给每个li都添加相同的点击事件,这时候我们通常会用for循环的方法,遍历所有元素,然后给他们添加点击事件,虽然看似内心毫无波澜很合理的做法,背后实则存在着巨大的性能弊端。
在JS中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与DOM节点进行交互,所以访问DOM的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思路就是从减少DOM操作的角度去入手的原因。
这种情况,如果用时间委托,就会将所有的操作都放到JS程序里面,与DOM的操作就只需要交互一次,这样就能大大的减少与DOM的交互次数;并且,每一个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,性能自然就会越差,如果使用事件委托,我们就可以只对它的父级这一个对象进行操作,这样我们就值需要一个内存空间就够了,大量节省了内存空间,提高整体页面的性能了。
给外层div加点击事件,通过event.target获取到点击的dom元素
给点击的列的元素绑定 属性,这里我绑定了id
和自定义属性data-obj
对象,直接把改列的item添加进去,不用一个一个单独绑定。
点击方法,把原来的点击方法取消,直接在这个底部调用。、
写了一个比较通用的方法其它几个页面按照这个方法也很好用,不用一个个绑定,那个类row纯属做了一个标志位,便于循环之后的判断,如果不清楚,直接console.log,便于定位每个变量。
大功告成。