javascript - 如何使自定义范围输入适用于触摸屏?

标签 javascript touch

我有一个自定义范围 slider 。

但是,我遇到的问题是,我无法在触摸设备上实现自定义“拇指”(在本例中为 🔥)的滑动。

这是实时项目:https://wagon-city-guides.herokuapp.com/spots/32

如果你在你的手机上检查它(我使用iPhone),你仍然会看到原始拇指的边框(我现在故意留下它),它可以滑动并工作,但是火焰(自定义拇指) ) 没有出现……虽然它对于点击设备运行良好。

我只是在寻找 Vanilla JS 解决方案。 🙏🏽

这是我的代码:

class RatingSlider {
  constructor() {
    this.ratingSliderForm = document.querySelector(".js-rating-slider-form");
    this.ratingSliderInput = document.querySelector(".js-rating-slider-input");
    this.ratingSliderThumb = document.querySelector(".js-rating-slider-thumb");
    this.ratingSliderValue = document.querySelector(".js-rating-slider-value");
    this.ratingSliderIcon = document.querySelector(".js-rating-slider-icon");
    this.isPressed = false;
    this.moveEvent;
    this.holdEvent;
    this.releaseEvent;
    this.bind();
  }

  handleSliding(event) {
    if (!this.isPressed) {
      return;
    }
    if (
      event.offsetX > 0 &&
      event.offsetX < this.ratingSliderInput.offsetWidth
    ) {
      this.ratingSliderThumb.style.left = `${event.offsetX - 10}px`;
      this.ratingSliderIcon.style.transform = `scale(${1 +
        this.ratingSliderInput.value / 150})`;
      this.ratingSliderValue.innerText = `${this.ratingSliderInput.value}°`;
    }
  }

  setRating() {
    this.ratingSliderThumb.style.left = `${(this.ratingSliderInput.offsetWidth /
      100) *
      this.ratingSliderInput.value -
      10}px`;
    this.ratingSliderIcon.style.transform = `scale(${1 +
      this.ratingSliderInput.value / 150})`;
    this.ratingSliderValue.innerText = `${this.ratingSliderInput.value}°`;
    this.ratingSliderInput.addEventListener(
      `${this.holdEvent}`,
      () => (this.isPressed = true)
    );
    this.ratingSliderInput.addEventListener(`${this.releaseEvent}`, () => {
      this.isPressed = false;
      this.ratingSliderForm.submit();
    });
  }

  setEvents() {
    if ("ontouchstart" in document.documentElement) {
      this.moveEvent = "touchmove";
      this.holdEvent = "touchstart";
      this.releaseEvent = "touchend";
    } else {
      this.moveEvent = "mousemove";
      this.holdEvent = "mousedown";
      this.releaseEvent = "mouseup";
    }
  }

  bind() {
    if (!this.ratingSliderForm) {
      return;
    }
    this.setEvents();
    this.setRating();
    this.ratingSliderInput.addEventListener(`${this.moveEvent}`, event =>
      this.handleSliding(event)
    );
  }
}

export default RatingSlider;

最佳答案

问题是触摸事件没有 offsetXoffsetY 属性。它们的值在移动设备中返回undefined。因此,您需要将它们添加到事件中。

handleSliding(event) 方法的开头添加以下内容:

if ("ontouchstart" in document.documentElement) {
  event = addOffsetsOnTouch(event);
}

function addOffsetsOnTouch(e) {
  let touch = e.touches[0] || event.changedTouches[0];
  let target = document.elementFromPoint(touch.clientX, touch.clientY);
  event.offsetX = touch.clientX - target.getBoundingClientRect().x;
  event.offsetY = touch.clientY - target.getBoundingClientRect().y
  return e;
}

关于javascript - 如何使自定义范围输入适用于触摸屏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61003510/

相关文章:

wpf - 如何使 WPF 输入控件在触摸屏上获得焦点时显示虚拟键盘

Android 检测来自任何应用程序的触摸状态

javascript - 如何在 jquery 自动完成中绑定(bind)按键事件?

javascript - 删除 Javascript/JQuery 中第一组引号之外的所有内容

javascript - 为什么我的 javascript for 循环不起作用? for (var i=1; i<5; i++;) { document.write ("A statement has run "); }

javascript - 如何将 touchstart 事件正确转换为 mousedown?

javascript - 在触摸设备上捕获并停止拖动

android - 如何通过在抽屉外触摸来防止关闭抽屉导航

javascript - 将 slideToggle() 添加到函数中

javascript - 用 span 包裹字符串