修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 前端
  4. JavaScript
  5. 正文

swiper 的内容滑动

2024年9月2日 2841点热度 0人点赞 0条评论

前阵子接到一个需求,写一个新闻类的 app,内容高度不定,而且还要可以上下翻页滑动。想了一下,最简单的方案应该就是全屏 swiper,这样我可以少些很多动作事件。

但是写着写着发现有一个问题,swiper 一般都是图片滑动,对应广告之类的,一夜一页的翻转查看,而缺少内容滑动的机制。而当我设置了内容可以滑动时,当到顶或者到底之后,缺失了全屏翻页的事件,这就很难受。只能自己去判断了。

使用到的内容:

  • vue-awesome-swiper@^4
  • swiper@^5

要判断其实也不难,方案很多,但都不尽善尽美。最后发现通过单独控制 allowSlidePrev 和 allowSlideNext 的方案是最好的。

首先,在内部页面组件中绑定 touchstart 和 touchmove 事件,end 不太需要。

我们要实现的效果是每次滑动时,判断是否可以上/下滑屏即可,所以判断的工作放在 start 事件中就刚刚好,move 事件只负责动态更新状态,方便下次滑动时使用即可。

然后,我们需要在 touchmove 事件中更新内容滚动高度,并更新位置状态:

onTouchmove(e) {
    if (this.isAtTop && this.isAtBottom) return;

    const currentY = e.touches[0].clientY;
    const diff = this.movedY - currentY;

    if (this.isAtTop && diff < 0) return;
    if (this.isAtBottom && diff > 0) return;

    this.ref.scrollTop += diff;

    // 判断是否到达顶部或底部
    this.isAtTop = this.ref.scrollTop === 0;
    this.isAtBottom =
    this.ref.scrollHeight - this.ref.scrollTop - this.ref.clientHeight < 2;

    this.movedY = currentY;
    e.preventDefault();
}

接下来,在 touchstart 事件中,分别判断当前页面是否处于顶部/底部,这两个分别判断,并抛出对应值,方便 swiper 接收:

onTouchstart(e) {
    this.movedY = e.touches[0].clientY;

    this.isAtTop = this.ref.scrollTop === 0;
    this.isAtBottom =
    this.ref.scrollHeight - this.ref.scrollTop - this.ref.clientHeight < 2;

    this.$emit("allowPrev", this.isAtTop);
    this.$emit("allowNext", this.isAtBottom);
}

ref 是整屏内容

需要注意的是,我们获取,当我们获取到这个页面元素的高度后,不能直接使用纯等的方式判断(顶高+屏高 === 滚动高度),有时候浏览器会返回小数,这会导致永远不会到底,所以使用一个相对值即可。

最后,我们只需要在 swiper 中接收对应事件,并更新状态即可:

<comp
    @allowPrev="v => {$refs.swiperRef.$swiper.allowSlidePrev = v}"
    @allowNext="v => {$refs.swiperRef.$swiper.allowSlideNext = v}"
/>

swiperRef 绑定对应的 Swiper 组件


这样,就基本实现了一个简单的页面翻页滑动,并且内容可以自己滑动,当滑动到顶部/底部的时候,不会再滑动,而是等下一次滑动时,会触发 swiper 的翻页,这种体验效果是最好的。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: vue
最后更新:2024年9月2日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

最新 热点 随机
最新 热点 随机
node-sass 的安装 解决端口被占的问题 vue3 组件 Props 的声明方式 给 div 添加选中状态 请求的取消 rgb 颜色小数兼容问题
JavaScript 之 canvas(二)-- 绘制基本图形 请求的取消 JavaScript 之 canvas(三)-- 使用鼠标实时绘制图形 MySql中timestamp创建日期的时区问题 真丶深入理解 JavaScript 原型和原型链(四):ES6中的class IdentityServer4深入使用(四)-- IdentityServer4 的使用

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号