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

标签 javascript html css overflow

我有一个 input rangediv包含在外部 div小于内部 div .最后的结果是我内心的div水平滚动(因为外部潜水有 overflow: scroll ),而 input range是它的 child 。
为了自定义范围,我用 appearance: none 删除了 CSS 中的外观。 .现在,这就是发生的事情。当我在 Chrome 开发人员的工具中检查它时(实际上我使用的是 Brave,但我猜它在 Chrome 中与我在 Chromium 中测试的结果相同,并且它是相同的)并且智能手机选项处于事件状态,如果我有 99% 的时间尝试移动范围 handle 它会移动整个 div用它。现在,如果我禁用智能手机选项,它就可以正常工作。另外,如果我保留智能手机选项并删除 appearance: none从 CSS 中,它也可以正常工作,但是我对范围的自定义消失了。有谁知道发生了什么?
PS.:在 Firefox 中,input range只要我保持智能手机选项打开(无论我是否具有外观属性),它就不起作用。
这是我的意思的动画 gif:
首先,我有上面描述的 input range没有出现。它工作正常,我可以移动可滚动的 div并移动 input range独立处理。然后我把 appearance: noneinput range (注意输入范围的格式发生了变化),现在我无法移动 input range独立于可滚动的 div 处理了。最后,从 input range 中删除外观,一切都恢复正常(但我的自定义已消失)
Text
这是代码,但您只能使用开发人员的工具在智能手机选项处于事件状态的情况下进行模拟,您可以在其中模拟触摸。

<!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>

编辑:
使固定:
Oleg Barabanov,建议制作 overflow: hidden同时移动输入句柄(在 touchstart 上添加一个类并在 touchend 上删除类)。虽然可行,但我想到了一个更优雅的解决方案。我记得event.preventDefault()以及它如何让我们取消浏览器对后续事件的处理。这个想法是,如果我可以允许一个事件,input事件并阻止其余的(浏览器自动完成的滚动事件)然后它可以工作。
这是我第一次尝试输入范围的附加代码:
    document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) =>

document.querySelector('.outerframe').classList.add("overflow-hidden");
      evt.preventDefault();
    });
它在这里不起作用(这让我感到惊讶,因为我过去成功地使用它来停止默认事件)。但后来我想起,当我研究 JS 事件时,还有另一种方法可以防止默认事件,那就是 return false for the event :
    document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) =>

document.querySelector('.outerframe').classList.add("overflow-hidden");
      return false;
    });
公平地说,那篇文章提到 return false仅适用于将事件配置为像 ontouchstart 这样的属性时。 .但我用 addEventListener()方法,它也有效。
我希望它在 future 可以帮助更多的人。

最佳答案

也许这不是最好的解决方案,但它似乎有效。只需使用 touchstarttouchend事件 + 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");
});
#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;  
}
<!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>

关于javascript - 模拟智能手机时,输入范围在可滚动 div 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69515789/

相关文章:

javascript - 是否可以避免 Chart.js 饼图在附上标签时缩小?

javascript - 当函数再次发生时,第一次使用函数加载的图像是隐藏的

javascript - chrome.tabs.executeScript : How to get access to variable from content script in background script?

jquery - django bootstrap 下拉菜单不工作

javascript - Node js : HTTP POST : Error: Can't set headers after they are sent

html - CSS 定位 : Content that should be below the fold is appearing above the fold

html - 正确创建带有导航的标题?

css - 突然错位的导航栏

css - CSS 高度的 DOCTYPE 问题

html - 输入字段处于焦点时占位符不会消失