深入解决Mac触控板滑动事件(浏览器前进、后退丢失页面)

今天在开发的时候 ,产品就给我了这个需求,问我可不可以在mac上去支持对于触控板的滑动事件,进行前后翻页呢,然后我不就得开始开发了吗,然后就在开发得时候遇到一系列得问题,比如进行左右滑动的时候会触发浏览器的默认事件导致丢失页面,和对于处理较复杂的手势(进行转着圈滑动)时,出现多次滑动事件翻页,但是还是一一解决了,直接上代码
 

let debounceTimeoutX = null; // 用于水平滚动的防抖定时器
const debounceDelayX = 150; // 水平滚动防抖延迟时间(毫秒)

let debounceTimeoutY = null; // 用于垂直滚动的防抖定时器
const debounceDelayY = 180; // 垂直滚动防抖延迟时间(毫秒)

let lastScrollTime = 0; // 记录最后一次滚动的时间
const scrollCooldown = 500; // 防止重复触发的冷却时间(毫秒)
const threshold = 10; // 滑动阈值
let currentDirection = null; // 当前正在处理的滑动方向

const handleWheelEvent = (event) => {
  // 阻止默认的滚动行为
  event.preventDefault();

  const now = Date.now();
  if (now - lastScrollTime < scrollCooldown) {
    // 如果距离上次翻页的时间小于冷却时间,则不执行翻页
    return;
  }

  const deltaX = event.deltaX;
  const deltaY = event.deltaY;

  console.log("deltaX:", deltaX, "deltaY:", deltaY);

  // 判断滑动方向是主要水平还是垂直
  if (Math.abs(deltaX) > Math.abs(deltaY) && currentDirection !== "vertical") {
    // 主要为水平滑动,且当前没有正在处理垂直滑动
    if (Math.abs(deltaX) > threshold) {
      // 清除上一个防抖定时器
      if (debounceTimeoutX) clearTimeout(debounceTimeoutX);

      // 设置当前滑动方向为水平
      currentDirection = "horizontal";

      // 设置新的防抖定时器
      debounceTimeoutX = setTimeout(() => {
        lastScrollTime = Date.now(); // 更新最后一次滚动的时间
        if (deltaX > 0) {
          console.log("Scrolled right");
          goToNextSlide(); // 向右翻页
        } else {
          console.log("Scrolled left");
          goToPreviousSlide(); // 向左翻页
        }
        currentDirection = null; // 重置滑动方向
      }, debounceDelayX);
    }
  } else if (
    Math.abs(deltaY) > threshold &&
    currentDirection !== "horizontal"
  ) {
    // 主要为垂直滑动,且当前没有正在处理水平滑动
    if (debounceTimeoutY) clearTimeout(debounceTimeoutY);

    // 设置当前滑动方向为垂直
    currentDirection = "vertical";

    // 设置新的防抖定时器
    debounceTimeoutY = setTimeout(() => {
      lastScrollTime = Date.now(); // 更新最后一次滚动的时间
      if (deltaY > 0) {
        console.log("Scrolled down");
        goToNextSlide(); // 下翻页
      } else {
        console.log("Scrolled up");
        goToPreviousSlide(); // 上翻页
      }
      currentDirection = null; // 重置滑动方向
    }, debounceDelayY);
  }
};

当然我这个场景是翻页的业务场景感兴趣的可以看看我的翻页函数
 

// 下翻页
function goToNextSlide() {
  const pptxContainer = document.getElementById("slide-container");
  if (pptxContainer) {
    const slides = pptxContainer.querySelectorAll(".slide");
    if (slides.length > 0) {
      if (currentPage.value >= slides.length - 1) {
        ElMessage.info({
          message: "已经是最后一页了",
          duration: 1000,
        });
        return; // 阻止进一步操作
      }
      currentPage.value = (currentPage.value + 1) % slides.length;
      updateSlides(slides);
    }
  }
}

// 上翻页
function goToPreviousSlide() {
  const pptxContainer = document.getElementById("slide-container");
  if (pptxContainer) {
    const slides = pptxContainer.querySelectorAll(".slide");
    if (slides.length > 0) {
      if (currentPage.value <= 0) {
        ElMessage.info({
          message: "已经是第一页了",
          duration: 1000,
        });
        return;
      }
      currentPage.value =
        (currentPage.value - 1 + slides.length) % slides.length;
      updateSlides(slides);
    }
  }
}

最后就是绑定事件了,这里面配置就是可以防止页面默认事件的对于会出现的页面丢失的问题
 

// 绑定鼠标滚动事件
    window.addEventListener(
      "wheel",
      (event) => {
        event.preventDefault();
        handleWheelEvent(event);
      },
      { passive: false }
    );

各位前端觉得有帮助的话,那我很会自豪的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值