0

I have this code in jQuery which works well, but I'm trying to transform it to vanilla JS (plain JavaScript), at first I will show you code in jQuery:

var prev = 0;
var $window = $(window);
var nav = $('.nav');

$window.on('scroll', function(){
  var scrollTop = $window.scrollTop();
  nav.toggleClass('hidden', scrollTop > prev);
  prev = scrollTop;
});
body {
  font-family: helvetica neue, helvetica, arial, sans-serif;
  height: 8000px;
}

.nav {
  background: #111;
  text-align: center;
  color: #fff;
  height: 20px;
  padding-top: 20px;
  padding-bottom: 20px;
  position: fixed;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
  -moz-transition: -moz-transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
  transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.nav.hidden {
  -webkit-transform: translateY(-100%);
  -moz-transform: translateY(-100%);
  -ms-transform: translateY(-100%);
  -o-transform: translateY(-100%);
  transform: translateY(-100%);
}

p {
  margin: 0;
  padding: 20px;
<script
  src="https://code.jquery.com/jquery-3.6.1.min.js"
  integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ="
  crossorigin="anonymous"></script>

<div class="nav">Scroll to show/hide this bar!</div>

<p>They see me scrolling...</p>
<p>Scroll down and back up to view the nav</p>

and here is code in vanilla js I made getting this error:

Uncaught SyntaxError: Failed to execute 'querySelector' on 'Document': '[object Window]' is not a valid selector.

var prev = 0;
var $window = document.querySelector(window);
var nav = document.querySelectorAll(".nav");

$window.addEventListener("scroll", function () {
  var scrollTop =
    window.pageYOffset ||
    document.documentElement.scrollTop ||
    document.body.scrollTop ||
    0;

  if (scrollTop > prev) {
    nav.classList.toggle("hidden");
  }

  prev = scrollTop;
});

Can someone tell me where I am making a mistake please.

var prev = 0;
var nav = document.querySelectorAll(".nav");

window.addEventListener("scroll", function () {
  var scrollTop =
    window.pageYOffset ||
    document.documentElement.scrollTop ||
    document.body.scrollTop ||
    0;

  if (scrollTop > prev) {
    nav.classList.toggle("hidden");
  }

  prev = scrollTop;
});

We solve problem on window object, but now we get another error on classlist toggle like:

Uncaught TypeError: Cannot read properties of undefined (reading 'toggle')

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
ByGio1
  • 111
  • 2
  • 12
  • 4
    The error message is very clear. Your code starts with querySelector(window), but "window" is not a valid selector. Remove that line of code and change $window to just window on the line down. – Yogi Sep 28 '22 at 15:11
  • 1
    You'll also find jquery helpfully hides the distinction between a single element and an element collection (by always being a collection and having methods apply to the collection). The next error you'll get is `nav.classList.` as classList isn't a property of a `NodeList` – freedomn-m Sep 28 '22 at 15:15
  • @Yogi you're right, it solve error at first, but now i get another issue just like freedomn-m tell us, "Uncaught TypeError: Cannot read properties of undefined (reading 'toggle')" – ByGio1 Sep 28 '22 at 17:34
  • @freedomn-m sir can you tell me how can i do it? maybe in a for...of loop... in with classList.add and classList.remove or better NodeList.forEach() method. – ByGio1 Sep 28 '22 at 17:58
  • 1
    Please don't ask a question, get an answer, then edit your question with a new question. Ask a new question with your new question. – Heretic Monkey Sep 28 '22 at 18:29
  • @HereticMonkey thanks for guide me on forum :) – ByGio1 Sep 28 '22 at 18:59

1 Answers1

1

First of all querySelectorAll returns all the elements in an array. Since you only have one .nav bar you can just change it to .querySelector(".nav") instead.

And also the scroll will not work as expected. You can't use .toggle("hidden");. When you use toggle you are constantly telling the navbar to show and hide every time you scroll.

If you are scrolling down, we add hidden class nav.classList.add("hidden"); If you are scrolling up we remove hidden class nav.classList.remove("hidden");

var prev = 0;
var nav = document.querySelector(".nav");

window.addEventListener("scroll", function () {
  var scrollTop = window.pageYOffset || 0;

  if (scrollTop > prev) {
    nav.classList.add("hidden");
  } else {
    nav.classList.remove("hidden");
  }

  prev = scrollTop;
});
Henrik Maaland
  • 210
  • 2
  • 14