jquery轮播广告:给ul添加事件委托,仅子元素li可触发
写轮播图代码之际,九成开发者会于事件绑定以及this指向上遭遇困境,你所碰到的此问题恰是jQuery跟ES6语法相混杂使用时尤为显眼的陷阱,弄明白它你便能躲开前端开发里超级常见的那些棘手之处。
this指向的迷失与找回
JavaScript里头的this,可说是语言设计方面的一个相当大的槽点,它跟其他语言不一样,并非指向当前对象,反而是由函数的调用方式来决定。你写的代码里,第一个方案借助变量去保存this,虽说能够运行,然而这属于那种“用战术上的勤奋去掩盖战略上的懒惰”,并没有真正搞明白问题的本质所在。
于jQuery的事件委托里,回调函数之中的this默认指向触发事件的DOM元素,此即li。然而你所期望的this却是包含左移方法的那个外层对象。采用that=this的写法等同于将正确对象锁于闭包里,虽可使用但并非足够优雅。
箭头函数出现的本意乃是解决this绑定的问题,不过箭头函数将会继承定义时刻那个this,并且并无获取jQuery重新绑定的那个DOM元素,这便使得你于箭头函数当中无法拿到li元素,因而需要借助事件对象e去进行获取。
事件源与目标元素的识别
你所提出的第二种方案,其方向是正确无误的,然而在实现的过程当中却存在着偏差,问题呈现于事件冒泡方面以及目标元素识别地方。当li被a进行包裹之后,在实际情况里触发事件的乃是a元素,可事件委托所监听的父元素却是un,这两者之间间隔着一层。
采用e.target的确能够获取到切实触发事件的a元素,然而你想要处理的却是li。能够运用closest方法从e.target朝着上方寻觅最近的li元素,或者径直使用e.delegateTarget获取绑定事件的ul,接着借助find方法去定位实际触发的li。
在具体去进行实现操作的时候,去判断e.target.tagName是不是LI这种方式是不太可靠的,这是由于当点击到a的时候tagName是A。应当使用$(e.target).closest('li')这种方式来获取li元素,要是存在的话那就表明点击是发生在li或者它的子元素上面的。
动态生成元素的事件绑定
在jQuery里动态生成的那些元素,平常普通的事件绑定办法是没效果的,得要使用事件委托才行,你代码当中出现的$('#.')这样的写法存在着一定问题,选择器好像是被截断了,更应该像$('#ulId')这样的具体的选择器才对。
事件委托的原理在于利用事件冒泡,把事件处理函数绑定于父元素之上,借助判断触发事件的子元素去执行相应逻辑。这般的方式不但支持动态的元素,而且能够减少事件处理函数的数量,进而提升性能。
在那种针对轮播图这般频繁去操作DOM的场景的情况下,事件委托可是特别地重要之处。每一回将新的轮播项给添加进去的时候,并不需要进行重新去绑定事件,所有的li元素都能够自动地获取到交互的能力。
箭头函数与传统函数的抉择
有一种函数叫箭头函数,它可不是能解决所有问题的万能良方,它不存在属于自身的this,也没有arguments,更没有super,并且它并不适宜被当作对象的方法来运用。在处理事件的情形当中,要是有需求去访问触发事件的DOM元素,那么传统函数相比较而言更为恰当;要是有需求去访问外层对象的属性以及方法,此时箭头函数反倒会显得更加便利。
你所面对的场景,实际上是需要在同一时刻去访求DOM元素以及外层对象,这存在着一定的矛盾之处。有一种显得优雅的解决办法是,于箭头功能之中留存外层的this,与此同时借助事件对象来获取DOM元素,如此一来既确保了法子调用的正确性,又能够精准地获取到li元素。
代码能够被写成,$('#ulId').on('mouseenter', 'li', (e) => { const $li = $(e.currentTarget); this.moveLeft(); }) ,如此这般,e.currentTarget所指向的便为监听的li元素,然而this却是外层对象。
轮播图功能的完整实现思路
存有索引管理以及动画切换的轮播图核心之处在所,于你的代码里边,利用index去获得当下li的位置,随后借由old来保留先前的索引,依靠差值去判定移动的方向,这样的思路是正确无误的。
达成左移方式的实现之际,得要考量边界情形,当当下索引是0之时,左移理应转换至最后一屏,当索引为最大值之际,右移应当切换至第一屏,这般循环轮播的感受最为契合用户期望。
以jQuery的animate方法来达成动画实现,借此操控轮播容器left值予以变动,顾及性能层面的着想,常常将会事先算计好全体轮播项的宽度,并且设定父容器overflow:hidden用以隐匿非当下的项。
代码重构与最佳实践
总体而言,你所书写的代码能够被重新构建成更为明晰的样式。首先,于外层对象之内界定好轮播相关联的方法,接着,在事件委托里运用箭头函数来维持this的指向,与此同时,借助事件对象的currentTarget属性去获取确切的元素。
此外值得注意得代码可读特性以及可维护特性,变量命名应当具备语义化性质,切不可采用i、old这类模糊不清得命名方式,对于索引管理环节能够通过抽象成独立得方法来予以实现,进而减少重复代码,在性能层面,针对频繁调用得index计算可斟酌缓存结果。
尽管轮播图十分常见,可实现细节内蕴诸多学问,事件处理,动画性能,响应式适配,每一个环节都极有深入思考的价值,你当下所碰到的问题,恰恰是提升代码质量的绝佳契机。
此刻你代码里头还有哪些致使你感到困惑之处呢?欢迎于评论区域分享你那轮播图的实现办法,点赞并转发,以使更多开发者避开这些陷阱。


