Listen for Arrow keys/Mousewheel to scroll site?!

Hey guys, I am creating a website that is essentially a sidescroller, a 1 page website that is horizontally scrolling. I want there to be as little confusion as possible, so when a user presses the arrow down key I want the page to scroll right (forward 1 section id) and when they press up I want to go back up 1 section id. I also want to listen for mousewheel scroll down and up respectively.

Here is a pen of the side scrolling I currently have.

I think what I would need is event listeners however, how do I event listen for these and THEN choose exactly where to go just like as if they were clicking the navbar?
Thanks!

No link to the pen there! If you can’t post links yet, then just the last part of the URL should do (eg DanielCouper/pen/QoJbeJ)

For the events though, write one function to handle scrolling left and one for scrolling right (just console.log at first to check it works), then

window.addEventListener('keydown' /* or keyup, see what feels better when you test it */, e => {
  switch (e.code) {
    case "ArrowUp":
      scrollLeft();
      break;
    case "ArrowDown":
      scrollRight();
      break;
    default:
      /* don't do anything */
  }
});

window.addEventListener('wheel', e => {
  if (e.deltaY < 0 /* or some negative number so it doesn't fire on the slightest touch*/) {
    // scrolled up
    scrollLeft();
  } else if (e.deltaY > 0 /* or some positive number so it doesn't fire on the slightest touch*/) {
    // scrolled down
    scrollRight();
  }
});

Sorry here is the pen! https://codepen.io/anon/pen/jJRpKY

It seems my function on click for the nav link only works for the first link? Is this something to do with needing querySelectorAll or its only getting first child for some reason? :slight_smile:

document.querySelector('a[href^="#"]').onclick = function(e) {
  console.log(this);
  // target element id
  let id = this.getAttribute("href");
  let selected = document.querySelector(id);
  console.log(selected);
  selected.style.transform = "translateX(0%)";
  // prevent standard hash navigation (avoid blinking in IE)
  e.preventDefault(); //try removing and add stopPropogation?
  //e.stopPropogation();
};

On what platform? Because it’s working fine for me, I’ve tried Firefox and Chrome (both on desktop).

(Note that stopPropagation would be useful if you had, say, an area which all had some onclick behaviour attached to it, then inside that you had an element with an onclick behaviour that did something different: if you didn’t use stopPropagation on the internal element, then clicking it would trigger the outer behaviour)

So when you click two it shows the blue section two? and three the yellow one the red etc?

Im on chrome, windows. and tried firefox.

Also while im here, do you know how to add to the current value for transform? get computed style then add to it? :slight_smile:

Im console logging the object and it only logs when I click “one” :frowning:

Yup yup. That’s wierd, afaics I’m getting exactly the behaviour you’re trying for.

Yep. However, you should just be able to give each panel an index starting at 0, then the transform is going to be something as basic as index * 100%. Keep a record of of which panel is the current one in the JS, and it means your calculations are easier & you don’t need to figure out computed style.

My website is now scrolling up and down rather than sideways :frowning: Are you using JS to scroll, because i was trying to at just pure html smooth scroll was buggy if you clicked link as it was scrolling.

I think it was related to my scroll code as I didnt really need it, smooth scroll does it for me

Do you mean keep track by check classes and removing and adding or something else?

Ive done this so far

function scrollRight() {
  let selected = document.querySelector(".contentContainer");
  console.log(selected);
  selected.style.transform = "translateX(-100%)";
}
function scrollLeft() {
  let selected = document.querySelector(".contentContainer");
  console.log(selected);
  selected.style.transform = "translateX(0%)";
}

umm, am I looking at the same thing here? Following is based on that link from before, but it may be slightly different. I’m assuming you’re transforming the x-position of the container that hold all of the sections Anyway, I could see this:

scroller

You shouldn’t really need to check classes, something like:

const container = document.querySelector(".contentContainer");
// Get an array with all the sections
const sections = [...document.querySelectorAll('.section')];
// Need to know how many there are
const numSections = sections.length;
// Always going to start at 0. The maximum index is `numSections - 1`
let currentSectionId = 0;

Now you can check where you are and act accordingly:

function scrollRight() {
  let nextSectionId = (currentSectionId == numSections - 1) ? 0 : currentSectionId + 1;

  container.style.transform = `translateX(${currentSectionId * 100}%)`;
  currentSectionId = nextSectionId;
}

function scrollLeft() {
  let prevSectionId = (currentSectionId == 0) ? numSections - 1 : currentSectionId - 1;

  container.style.transform = `translateX(${currentSectionId * 100}%)`;
  currentSectionId = prevSectionId;
}

Oh this is very cool, I had issues but changed the *100’s to *-100’s and seems to be working! Just need to add some animation scrolling etc :slight_smile: Thank you Ill see what I can do with this

It seems when going left and right its always going the same direction? Never left always right? I tried using -100% and got this effect but if one is *100% and other is *-100% then the *100% action causes a white screen out of the width view.