【问题标题】:Specifically on mobile, scroll a div from anywhere (w/out using jQuery plugins)?特别是在移动设备上,从任何地方滚动一个 div(不使用 jQuery 插件)?
【发布时间】:2018-03-23 17:57:15
【问题描述】:

original question开始,我们已经成功地使用D3js检测了一个滚动事件,我们用它来从任何地方滚动div #scroll-content;但是,此解决方案适用于桌面,但不适用于移动设备。问题示例:

  • gh-pages - 示例适用于桌面,但不适用于移动设备。
  • jsfiddle - 示例适用于桌面,但不适用于移动设备。
  • (或见附件代码sn-p)

在移动设备上,我们如何从页面的任意位置滚动 div #scroll-content?一个成功的解决方案意味着我们可以将手指放在移动页面的任意位置,垂直滑动来滚动div#scroll-content

注意以下几点:

  1. 答案应该允许使用 CSS 网格。
  2. 答案可以包括 d3.v4
  3. answer 不应使用 jQuery(如 answer0 中所建议)
  4. answer 不应使用插件(如 answer1answer2 中所建议的那样)。
  5. 答案应该可以在 iPhone SE 上同时使用 Safari 和 Chrome。

var body = d3.select("body");
var scroll = d3.select("#scroll-content");

body.on("wheel", function() {
    scroll.property("scrollTop", +scroll.property("scrollTop") + d3.event.deltaY)
});
body, html {
  height: 100%;
  box-sizing: border-box;
  overflow:hidden; /* stops scroll from the entire page */
  background-color: #ad6364;
}
#wrapper {
  display: grid;
  height:100%;
  grid-template-columns: 25% repeat(10,7%) 5%;
  grid-template-rows: 5% repeat(4,15%) 30% 5%;
  grid-template-areas:
    "nav nav nav nav nav nav nav nav nav nav nav nav"
    "side1 side1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 side2"
    "side1 side1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 side2"
    "side1 side1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 side2"
    "side1 side1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 viz1 side2"
    "int   int  int  int  int  int  int  int  int  int  int  int"
    "ftr   ftr  ftr  ftr  ftr  ftr  ftr  ftr  ftr  ftr  ftr  ftr";
  grid-gap:1px;
}

#scroll-content {
  display:block;
  grid-column: 1/3;
  grid-row: 2 / 6;
  /*background-color:#ad6364;*/
  /*opacity: 0.75;*/
  overflow: auto;
  background-color:#2B3033;
}
.step{
  margin-bottom: 1000px;
  overflow: auto;
  max-height: 100vh;
  position: relative;
  fill:#bdbdc1;
}

#viz-container{
  background-color:#2B3033;
  grid-area: viz1;
}
#nav-bar{
  grid-area:nav;
  background-color:#767678;
}
#side-bar1{
  grid-area:side1;
  background-color:#767678;
}
#side-bar2{
  grid-area:side2;
  background-color:#767678;
}
#footer{
  grid-area:ftr;
  background-color:#767678;
}
#interaction{
  grid-area:int;
  background-color:#767678;
}
.general-text{
  text-align: center;
  vertical-align: middle;
  color:#bdbdc1;
  font-size:12px;
}
<html>
  <head>
    <meta charset="utf-8">
    
    <!-- D3 -->
    <script src="https://d3js.org/d3.v5.min.js"></script>

    <!-- linked CSS -->
    <link href="style.css" type="text/css" rel="stylesheet">
  </head>
  <body>
    <div id="wrapper">
      <div id="nav-bar" class="general-text">nav</div>
      <div id="scroll-content" class="general-text">
        <section class="step">Question: ON MOBILE, how do we make this div #scroll-content scrollable from anywhere on the page? <br><br>Notice ON DESKTOP that if we place the mouse anywhere, this div currently scrolls, which is the correct behavior desired for MOBILE; however, ON MOBILE this div can not be scrolled. <br><br>...scroll down.
        </section>
        <section class="step">Note: none of the div positions are fixed b/c we're using CSS Grid.<br><br>...scroll down.
         </section>
         <section class="step">...the end.
         </section>
      </div>
      <div id="viz-container" class="general-text">viz</div>
      <div id="interaction" class="general-text">interaction</div>
      <div id="side-bar1"></div>
      <div id="side-bar2"></div>
      <div id="footer" class="general-text">footer</div>
    </div>
    <!-- create listener -->
    <script src="scroll.js" type="text/javascript"></script>
  </body>
</html>

【问题讨论】:

  • 尝试使用“scroll”事件而不是“wheel”。这就是问题所在。
  • 为此使用 d3 是完全没有必要和矫枉过正的。你可以从scrollTop-lastScrollTop或类似的地方找到delta y

标签: javascript html d3.js mobile scroll


【解决方案1】:

滚动鼠标滚轮时会触发wheel 事件。手机没有鼠标,而是有触摸屏。

一个更通用的事件,scroll 事件将在检测到滚动时触发,浏览器可以决定何时触发,这意味着它适用于桌面鼠标滚轮滚动和触摸设备滚动。

但是,如果页面高度小于视口高度的 100%,滚动事件似乎不会触发。我不确定车轮事件是否属实。如果是,那么除了触摸事件之外,以下解决方案还需要包括鼠标事件(mousedownmousemove 等)。


考虑到您想要更多自定义行为,无论用户在屏幕上滚动的位置如何滚动元素,并且页面不需要物理滚动,您只想捕获该事件并使用它,它可能需要创建自定义滚动功能;使用document.body 上的touchstarttouchmovetouchend 事件触发#scroll-content 的自定义滚动代码。您也可以使用 wheel 事件来触发滚动代码,因此它也适用于桌面。

这看起来像这样:

  1. 在触摸开始时,存储触摸的 y 坐标。 startY = e.touches[0].pageY;
  2. 在触摸移动时,找到开始 y 和移动 y 之间的增量。 deltaY = startY-moveY;
  3. 使用此增量触发自定义滚动事件。 customScroll(deltaY)

自定义滚动事件将采用增量并将其应用到 #scroll-content 使用类似 element.scrollBy(0, deltaY) 的东西

您可能还需要对 deltaY 进行归一化,因为车轮 deltaY 可能是不同的大小,例如*100 或倒数等。


这只是对如何实现所需结果的简化描述。如果您不想使用诸如hammer.js 之类的插件/库,那么您将需要自己编写自定义代码。祝你好运。

【讨论】:

  • 移动设备上的scroll 活动不走运。请参阅these changes 并在您的手机上尝试此test page。也许adjustScrolling 实际上是问题所在?
  • 确实,我建议您忽略我回答中文本的顶部,而专注于中间部分。您的代码不包含任何带有触摸事件的自定义滚动。
猜你喜欢
  • 1970-01-01
  • 2014-10-13
  • 2013-04-28
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 2022-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多