如何使用javascript检测不可滚动元素中的滚动事件和方向

How to detect scroll event and direction in a not scrollable element using javascript?

本文关键字:滚动 事件 方向 元素 javascript 检测 何使用      更新时间:2023-09-26

我正在尝试模拟终端滚动行为,它只是立即将视图移动3行,而没有平滑的滚动动画。

这是我简化的CSS和HTML结构:

body {
  overflow: hidden;
  font-size: 13px;
  line-height: 1.2em;
}
section {
  width: 100%;
}
section#tabs {
  position: fixed;
  top: 0;
  background-color: grey;
}
section#main {
  margin: 15px 0;
}
section#controls {
  position: fixed;
  bottom: 0;
  background-color: grey;
}
section#imgView {
  position: fixed;
  top: 100%;
  background-color: red;
}
<html>
  <body>
    <article>
      <div data-reactroot>
        <section id="tabs">
          <span>[abc]</span>
          <span>[bcd]</span>
          <span>[cde]</span>
          <span>[def]</span>
          <span>[efg]</span>
        </section>
        <section id="main">
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
        </section>
        <section id="controls">
          <div>This will always be at the bottom.</div>
        </section>
        <section id="imgView">
          <div>You're not supposed to see this sentence.</div>
        </section>
      </div>
    </article>
  </body>
</html>

部分tabscontrols将在浏览器中粘贴到它们各自的边上,并且imgView将不可见,除非某些代码通过更改其与位置相关的属性来调用它。

我做了它,所以主体有overflow: hidden;,我不能使用比较当前滚动位置和前一个滚动位置的方法。

只需收听滚动事件,然后向上或向下滚动3行。

var lineHeight = 18;
var scrollStep = lineHeight * 3;
var lastScrollY = 0;
var scrollContainer = document.querySelector("#main");
scrollContainer.addEventListener("scroll", function () {
    if (scrollContainer.scrollTop > lastScrollY) {
        scrollContainer.scrollTop = lastScrollY + scrollStep;
    } else if (scrollContainer.scrollTop < lastScrollY) {
        scrollContainer.scrollTop = lastScrollY - scrollStep;  
    }
    lastScrollY = scrollContainer.scrollTop;
});

我发现这个网站在解释mousewheelDOMMouseScroll事件。

该网站上的一个例子是,当你在容器上滚动时,图像容器会放大和缩小。所以我举了这个例子,让它滚动下面的body元素。

var body = document.body;
var MouseWheelHandler = function(e) {
  // these codes make it so `delta` return 1 for up and -1 for down in any browser exclude Safari.
  var e = window.event || e;
  var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
  
  // to cancel the normal scrolling behavior
  e.preventDefault();
  
  if(delta===-1) { body.scrollTop += 45; }
  if(delta===1) { body.scrollTop -= 45; }
  
  // this is meant to cancel the normal scrolling behavior. Doesn't work here...
  return false;
}
if (body.addEventListener) {
  // IE9, Chrome, Safari, Opera
  body.addEventListener("mousewheel", MouseWheelHandler, false);
  // Firefox
  body.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
  // IE 6~8
} else body.attachEvent("onmousewheel", MouseWheelHandler);
body {
  overflow: hidden;
  font-size: 13px;
  line-height: 1.2em;
}
section {
  width: 100%;
}
section#tabs {
  position: fixed;
  top: 0;
  background-color: grey;
}
section#main {
  margin: 15px 0;
}
section#controls {
  position: fixed;
  bottom: 0;
  background-color: grey;
}
section#imgView {
  position: fixed;
  top: 100%;
  background-color: red;
}
<html>
  <body>
    <article>
      <div data-reactroot>
        <section id="tabs">
          <span>[abc]</span>
          <span>[bcd]</span>
          <span>[cde]</span>
          <span>[def]</span>
          <span>[efg]</span>
        </section>
        <section id="main">
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>some texts that is long enough to make this snippet properly represent some shape I want to show</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
          <div>another texts to tell the difference on the height</div>
        </section>
        <section id="controls">
          <div>This will always be at the bottom.</div>
        </section>
        <section id="imgView">
          <div>You're not supposed to see this sentence.</div>
        </section>
      </div>
    </article>
  </body>
</html>