Dinir Dinir - 7 months ago 64
Javascript Question

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

I am trying to simulate Terminal scroll behavior, which just immediately move the view by 3 lines, without smooth scrolling animation.

Here is my simplified CSS and HTML structure:



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>





The section
tabs
and
controls
will be sticking to their respective edges in the browser, and
imgView
will not be visible unless some code calls it by changing its position related properties.

I made it so body has
overflow: hidden;
, I can't use methods of comparing current scroll position with previous one.

Answer

I found this site explaining about mousewheel or DOMMouseScroll event.

An example on that site is an image container zooms in and out when you scroll on the container. So I took the example and let it scroll the body element below.

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>