Angular 2+环境下Swiper与cdkDrag拖拽功能兼容问题咨询
问题原因
Swiper默认会拦截所有鼠标/触摸拖拽事件用于自身的滑动翻页逻辑,导致cdkDrag的触发事件被吞掉,所以出现拖拽失效的问题,二者是可以兼容的,按以下步骤调整即可:
解决步骤
1. 修改Swiper配置
在你的SwiperOptions中新增3个配置项,让Swiper跳过对拖拽元素的事件拦截:
config: SwiperOptions = { pagination: { el: '.swiper-pagination', clickable: true }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' }, spaceBetween: 30, loop: false, loopFillGroupWithBlank: false, initialSlide: 0, slidesPerView: 6, slidesPerGroup: 6, // 以下是新增的兼容配置 noSwiping: true, // 开启对指定类元素的滑动忽略 noSwipingClass: 'swiper-no-swiping', // 要忽略的元素类名,默认值可直接用 touchStartPreventDefault: false, // 不默认阻止touchstart事件,让cdkDrag可以拿到事件 on: { init: function () { console.log('swiper initialized'); }, slideChange: function () { console.log('swiper slideChange'); }, touchMove: function () { console.log('swiper Move'); }, tap: function () { console.log('tap'); }, touchStart: function () { console.log('touchStart'); }, }, };
2. 修改HTML代码
给绑定了cdkDrag的swiper-slide元素添加swiper-no-swiping类,同时可添加拖拽延迟,避免和Swiper滑动逻辑冲突:
<!-- 仅展示修改的swiper-slide部分,其余代码保持不变 --> <div class="swiper-slide pop swiper-no-swiping" *ngFor="let dataItem of appListService.normalAppList" cdkDrag [cdkDragStartDelay]="300" (cdkDragStarted)="onDragStarted()" (cdkDragEnded)="onDragEnded()"> <a class="apps {{dataItem.icon}}" (click)="gotoAppPage(dataItem)" draggable="false" style="cursor: pointer;"> <span class="icon"></span> <span class="title" id="landing-detailApp{{ dataItem.appCode }}">{{ dataItem.appName }}</span> </a> </div>
上面的[cdkDragStartDelay]配置表示按住元素300ms才触发拖拽,短按滑动还是触发Swiper翻页,符合普通用户的操作习惯。
3. 可选优化(拖拽过程禁用Swiper)
如果拖拽过程中不想触发Swiper滑动,可以在拖拽的生命周期回调中控制Swiper的可用状态:
首先在TS中获取Swiper实例:
// 组件类中新增代码 @ViewChild('usefulSwiper') usefulSwiper: any; onDragStarted() { // 拖拽开始时禁用Swiper this.usefulSwiper.swiperRef.disable(); } onDragEnded() { // 拖拽结束后重新启用Swiper this.usefulSwiper.swiperRef.enable(); }
内容的提问来源于stack exchange,提问作者Andrei
相关产品推荐
相关产品推荐

