模拟智能手机时,输入范围在可滚动 div 中不起作用

Adr*_*fas 6 html javascript css overflow

我有一个input rangein a包含在比内部小的div外部中。最终结果是我的内层滚动水平(因为外层有), 是它的子项。divdivdivoverflow: scrollinput range

为了自定义范围,我使用 删除了 CSS 中的外观appearance: none。现在,发生的事情是这样的。当我在 Chrome 开发者工具中检查它时(实际上我使用 Brave,但我猜它在 Chrome 中与我在 Chromium 中测试的相同,而且是相同的),并且智能手机选项处于活动状态,99% 的时间如果我尝试移动范围手柄,它会div随之移动整个物体。现在,如果我禁用智能手机选项,它就可以正常工作。另外,如果我保留智能手机选项并appearance: none从 CSS 中删除 ,它也可以正常工作,但我对该范围的自定义消失了。有谁知道发生了什么事吗?

PS.:在 Firefox 中,input range只要我保持智能手机选项打开(无论我是否有外观属性),该功能就不起作用。

这是我的意思的动画 gif: 首先,我有上面描述的input range没有外观的。它工作正常,我可以独立移动滚动条div和移动input range手柄。然后我将 放入appearance: noneinput range注意输入范围的格式更改),现在我无法再input range独立于可滚动来移动手柄div。最后,从 中删除外观input range,一切恢复正常(但我的自定义消失了) 文本

这是代码,但您只能使用开发人员工具在智能手机选项处于活动状态时进行模拟,您可以在其中模拟触摸。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
  <meta charset="UTF-8">
  <style>
    #outerframe {
      height: 310px;
      width: 300px;
      border: 2px solid red;
      padding: 8px;
      margin: auto;
      overflow: scroll;
    }

    #scrollarea {
      height: 300px;
      width: 400px;
      border: 1px dashed green;
      padding: 16px;
    }

    input[type=range] {
      appearance: none;
      background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa);
      outline: none;
      opacity: 0.7;
      border-radius: 4px;
      height: 14px;
      width: 200px;
      box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset;
      vertical-align: middle;
      margin: 16px;
    }

    input[type=text] {
      width: 50px;
    }
  </style>
  <title>Testing range in scroll</title>
</head>
<body>
  <div id="outerframe">
    <div id="scrollarea">
      <input type="range" id="rangescroll">
      <input type="text" value="50">
    </div>
  </div>

  <script>
    scrollarea.firstElementChild.addEventListener('input', evt => {
      evt.target.nextElementSibling.value = evt.target.value;
    })
  </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

编辑:修复:

overflow: hiddenOleg Barabanov,建议在移动输入手柄时进行(在touchstart上添加一个类并在touchend上删除该类)。虽然这有效,但我想到了一个更优雅的解决方案。我记得event.preventDefault()以及它如何允许我们取消浏览器对后续事件的处理。我的想法是,如果我可以允许一个事件,该input事件并阻止其余事件(浏览器自动完成的滚动事件),那么它就可以工作。

这是我第一次尝试输入范围的附加代码:

    document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) =>

document.querySelector('.outerframe').classList.add("overflow-hidden");
      evt.preventDefault();
    });
Run Code Online (Sandbox Code Playgroud)

它在这里不起作用(这对我来说很惊讶,因为我过去成功地使用它来停止默认事件)。但后来我想起来,当我研究 JS 事件时,还有另一种方法可以防止默认事件,那就是为事件返回 false

    document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) =>

document.querySelector('.outerframe').classList.add("overflow-hidden");
      return false;
    });
Run Code Online (Sandbox Code Playgroud)

公平地说,该文章提到这只return false适用于将事件配置为像 之类的属性ontouchstart。但我用了这个addEventListener()方法,也有效。

我希望它能在未来帮助到更多的人。

Ole*_*nov 1

也许这不是最好的解决方案,但它似乎有效。只需使用touchstartand touchendevents + css overflow

scrollarea.firstElementChild.addEventListener("input", (evt) => {
  evt.target.nextElementSibling.value = evt.target.value;
});
scrollarea.firstElementChild.addEventListener("touchstart", (evt) => {
  outerframe.classList.add("overflow-hidden");
});
scrollarea.firstElementChild.addEventListener("touchend", (evt) => {
  outerframe.classList.remove("overflow-hidden");
});
Run Code Online (Sandbox Code Playgroud)
#outerframe {
  height: 310px;
  width: 300px;
  border: 2px solid red;
  padding: 8px;
  margin: auto;
  overflow: scroll;
}

#scrollarea {
  height: 300px;
  width: 400px;
  border: 1px dashed green;
  padding: 16px;
}

input[type=range] {
  appearance: none;
  background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa);
  outline: none;
  opacity: 0.7;
  border-radius: 4px;
  height: 14px;
  width: 200px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset;
  vertical-align: middle;
  margin: 16px;
}

input[type=text] {
  width: 50px;
}

.overflow-hidden {
  overflow: hidden !important;  
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html lang="en">

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
  <meta charset="UTF-8">
  <title>Testing range in scroll</title>
</head>

<body>
  <div id="outerframe">
    <div id="scrollarea">
      <input type="range" id="rangescroll">
      <input type="text" value="50">
    </div>
  </div>


</body>

</html>
Run Code Online (Sandbox Code Playgroud)