如何修复移动端Slick Slider阻塞jQuery .show/.hide方法的问题?
问题描述
我在4个元素上使用Slick Slider,每个元素包含两层内容,通过点击按钮(用jQuery的.show()/.hide()方法)切换显示/隐藏。同时通过断点设置让滑块在移动端显示更少元素。
桌面端功能正常,但移动端无法切换内容层,jQuery的显示/隐藏方法像是被阻塞了。把窗口缩小再恢复原尺寸后,桌面端的切换功能也失效了。
请问该如何修复?
Slick Slider 代码
CSS 样式
.slick-slider { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-touch-callout: none; -khtml-user-select: none; ms-touch-action: pan-y; touch-action: pan-y; -webkit-tap-highlight-color: rgba(255,255,255,1); } .slick-center { -webkit-transform: scale(1.25); -moz-transform: scale(1.25); transform: scale(1.25); margin-left: 0vw !important; margin-right: 0vw !important; } @media(max-width: 980px) { .home-content-slider .slick-prev { left: -32px; } .home-content-slider .slick-next { right: -30px; } } @media(max-width: 499px) { .home-content-slider .slick-prev { left: -26px; } .home-content-slider .slick-next { right: -24px; } }
JS 初始化代码
jQuery(document).ready(function() { jQuery('.slide-home').slick({ speed: 800, autoplay: true, fade: false, autoplaySpeed: 10000, initialSlide: 2, dots: true, arrows: false, pauseOnHover: true, focusOnSelect: false, swipe: true, swipeToSlide: true, centerMode: true, slidesPerRow: 1, rows: 3, slidesToShow: 3, slidesToScroll: 1, touchMove: true, touchThreshold: 5, responsive: [ { breakpoint: 980, settings: { slidesToShow: 2, } }, { breakpoint: 767, settings: { slidesToShow: 1, } } ] }); });
显示/隐藏切换代码
jQuery(function($){ var buttons = { '.mtc_button_1up': { 'toggle': '', 'hide' : '.mtc_element_1up', 'show' : '.mtc_element_1down,.mtc_element_2up,.mtc_element_3up,.mtc_element_4up', }, }; $.each(buttons, function(button, elements) { $(button).click(function(e){ e.preventDefault(); $(elements.toggle).slideToggle(0); $(elements.show).slideDown(0); $(elements.hide).slideUp(0); $(button).toggleClass( 'mtc_button_opened mtc_button_closed'); }); }); }); jQuery(function($){ $('.mtc_button_1up').click(); });
修复方案
问题根源
Slick Slider在响应式断点切换时,会重新渲染DOM结构(比如克隆幻灯片、调整元素层级),导致原来直接绑定的点击事件丢失。另外,移动端的触摸事件可能和点击事件冲突,也会导致切换失效。
具体修复步骤
1. 用事件委托绑定点击事件
不要直接给按钮绑定点击事件,而是委托给静态的父容器(比如滑块的外层容器),这样即使Slick重新渲染DOM,事件依然有效。
修改显示/隐藏的JS代码:
jQuery(function($){ var buttons = { '.mtc_button_1up': { 'toggle': '', 'hide' : '.mtc_element_1up', 'show' : '.mtc_element_1down,.mtc_element_2up,.mtc_element_3up,.mtc_element_4up', }, }; // 委托给滑块容器(.slide-home是滑块初始化的容器) $('.slide-home').on('click', Object.keys(buttons).join(','), function(e){ e.preventDefault(); // 获取当前按钮的选择器 var buttonClass = $(this).attr('class').match(/mtc_button_\w+/)[0]; var buttonSelector = '.' + buttonClass; var elements = buttons[buttonSelector]; $(elements.toggle).slideToggle(0); $(elements.show).slideDown(0); $(elements.hide).slideUp(0); $(this).toggleClass( 'mtc_button_opened mtc_button_closed'); }); }); jQuery(function($){ $('.mtc_button_1up').click(); });
2. 监听Slick断点切换事件,重置状态
Slick提供了breakpoint事件,在断点切换时触发,可以在这个事件里重新设置元素的显示/隐藏状态,避免窗口resize后功能失效。
在Slick初始化代码中添加事件监听:
jQuery(document).ready(function() { var $slider = jQuery('.slide-home'); $slider.slick({ // 原有的配置项保持不变 speed: 800, autoplay: true, fade: false, autoplaySpeed: 10000, initialSlide: 2, dots: true, arrows: false, pauseOnHover: true, focusOnSelect: false, swipe: true, swipeToSlide: true, centerMode: true, slidesPerRow: 1, rows: 3, slidesToShow: 3, slidesToScroll: 1, touchMove: true, touchThreshold: 5, responsive: [ { breakpoint: 980, settings: { slidesToShow: 2, } }, { breakpoint: 767, settings: { slidesToShow: 1, } } ] }); // 监听断点切换,重置显示状态 $slider.on('breakpoint', function(event, slick, breakpoint){ // 重新触发初始点击,确保状态正确 $('.mtc_button_1up').click(); }); });
3. 解决移动端触摸事件冲突
禁用Slick的触摸事件与点击事件的冲突,在Slick配置中调整:
touchMove: false, // 或者保留touchMove,添加下面的CSS优化触摸体验
同时添加CSS优化移动端触摸反馈:
.mtc_button_1up { cursor: pointer; -webkit-tap-highlight-color: transparent; }
内容的提问来源于stack exchange,提问作者StudioSon
相关产品推荐
相关产品推荐

