You want to set the scrollTop property in the <main> element .
var nav = document.querySelector('nav'), main = document.querySelector('main'); nav.addEventListener('click', function(event){ var linkID, scrollTarget; if (event.target.tagName.toUpperCase() === "A") { linkID = event.target.dataset.goto.slice(1); scrollTarget = main.querySelector('[data-id="' + linkID + '"]'); main.scrollTop = scrollTarget.offsetTop; } });
You will notice a couple of other things that I did differently:
- I used event delegation , so I only had to bind one event to the
nav element, which would more efficiently handle clicks on any of the links. - Similarly, instead of iterating over all
p elements, I chose the one that wanted to use the attribute selector
It is not only more efficient and scalable, but also provides shorter and more convenient code.
This code will simply go to the element, for animated scrolling you will need to write a function that gradually updates scrollTop after slight delays using setTimeout .
var nav = document.querySelector('nav'), main = document.querySelector('main'), scrollElementTo = (function () { var timerId; return function (scrollWithin, scrollTo, pixelsPerSecond) { scrollWithin.scrollTop = scrollWithin.scrollTop || 0; var pixelsPerTick = pixelsPerSecond / 100, destY = scrollTo.offsetTop, direction = scrollWithin.scrollTop < destY ? 1 : -1, doTick = function () { var distLeft = Math.abs(scrollWithin.scrollTop - destY), moveBy = Math.min(pixelsPerTick, distLeft); scrollWithin.scrollTop += moveBy * direction; if (distLeft > 0) { timerId = setTimeout(doTick, 10); } }; clearTimeout(timerId); doTick(); }; }()); nav.addEventListener('click', function(event) { var linkID, scrollTarget; if (event.target.tagName.toUpperCase() === "A") { linkID = event.target.dataset.goto.slice(1); scrollTarget = main.querySelector('[data-id="' + linkID + '"]'); scrollElementTo(main, scrollTarget, 500); } });
Another problem that you may encounter when delegating events is that if the elements a contain child elements and a child element is inherited from them, this will be the purpose of the event, not the a tag. You can get around this with the getParentAnchor function that I wrote here .
source share