3
\$\begingroup\$

I've created a very plain version of page flip onscroll. I made it to look like turning the pages of a book. It looks OK on browsers I have (Firefox 52.9, Chrome 49, IE8). Though the effect doesn't work on IE8 and similar old browsers, it still doesn't look messy. I want to use this presentation method on a website.

  • Are there any parts of the code that I need to create a fallback for?
  • Could this page be faster?
  • Are there any accessibility concerns?
  • Are there any 'Best Coding Practices' that I need to include here?
  • Any other improvements?

New Question:

  • Will this effect make viewing a page uncomfortable on touch devices?

CodePen: https://codepen.io/ZechariahRaman/pen/NOYbXL/

var h = 0,
  r = 1,
  y = 0,
  yh = 1,
  section = document.getElementsByTagName("section"),
  d = section[0];

function load() {
  h = window.innerHeight;
  r = 180 / h;
  for (var i = section.length - 1; i >= 0; i--) {
    section[i].style.position = "fixed";
  }
}

function turn() {
  y = window.pageYOffset;
  if (y == 0) {
    section[0].style.transform = "initial";
  }
  if (y >= 0 && y < h) {
    yh = y;
    d = section[0];
    section[1].style.transform = "initial";
  }
  if (y >= h && y < h * 2) {
    yh = y - h;
    d = section[1];
  }
  d.style.transform =
    "perspective(" + h * 5 + "px) rotate3d(1,0,0," + r * yh + "deg)";
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  background-color: #274171;
  height: 300vh;
}

section {
  transform-origin: top;
  transition: all 0.3s ease;
}

#p1 {
  z-index: 3;
  background-color: #d9bd75;
}

#p2 {
  z-index: 2;
  background-color: #67a893;
}

#p3 {
  z-index: 1;
  background-color: #353cc9;
}

.page {
  margin: 1vh 9vw;
  height: 98vh;
  width: 80vw;
  display: flex;
}

p {
  margin: auto;
  font-size: 5em;
  padding: 0.5em;
  color: #fff;
  background-color: rgba(19, 41, 79, 0.7);
}
<body onload="load()" onresize="load()" onscroll="turn()">
  <section id="p1" class="page">
    <p>Hi</p>
  </section>
  <section id="p2" class="page">
    <p>Short Story</p>
  </section>
  <section id="p3" class="page">
    <p>The End</p>
  </section>
</body>

\$\endgroup\$
  • \$\begingroup\$ "It works OK on browsers I have (Firefox, Chrome, IE8). But I want to use this presentation method on a website." Yes, websites are usually viewed with a browser. Is there a problem? \$\endgroup\$ – Mast Oct 18 '18 at 7:17
  • \$\begingroup\$ That's my personal opinion - just about browser compatibility. I want a second opinion on whether the code/method could be better. Or perhaps more user friendly. I'm new to coding, so I was also hoping to see if there is anything I shouldn't have used or could have implemented differently. \$\endgroup\$ – Zechariah Raman Oct 18 '18 at 7:54
2
\$\begingroup\$

Declare variables in the smallest possible scope

It's recommended to declare variables in the smallest scope where they are needed. That way, the variable will not be visible where it should not be, and therefore it cannot be modified accidentally by mistake. It also makes understanding a program easier when you don't need to keep more variables in your head than necessary.

Therefore, since most of the variables are not needed in the global scope, move those declarations to the functions that need them.

Be careful with variable scope in JavaScript. Looking at this code, you may be mislead that the variable i is only visible within the loop:

  for (var i = section.length - 1; i >= 0; i--) {
    section[i].style.position = "fixed";
  }

But that's not the case. The variable is visible after the loop, and even before the loop (with value undefined).

In this particular example you want to replace the var with the let keyword, if your version of JavaScript supports it (like any non-ancient implementation). Using let, the variable will only be visible within the loop.

Avoid redundant variable initializations

In the posted code all variables are initialized at the time of declaration. But if the variables don't need an initial value, then this is just noise.

Order conditional terms by their values

It can improve readability when the terms in conditionals are in a consistent order. Take for example this piece:

  if (y >= 0 && y < h) {
    // ...
  }
  if (y >= h && y < h * 2) {
    // ...
  }

The first condition means y is between 0 and h, and the second means y is between h and h * 2. Although this is easy enough to see, the current writing style doesn't really help to see it.

Consider this alternative:

  if (0 <= y && y < h) {
    // ...
  }
  if (h <= y && y < h * 2) {
    // ...
  }

Now, the meaning hasn't changed, but it's much easier to see. And with this writing style, it's also easier to see that the two conditions will not be true at the same time, so the second if should in fact be an else if.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.