I am using a JS script to smoothly scroll to divs from links part of a listing of questions.
The script:
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = 0;
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 20);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
Then, the link must include an onclick event like this:
<a href="#this-is-a-question" rel="nofollow" onclick="smoothScroll(document.getElementById('this-is-a-question'))">This is a question?</a>
It works perfectly and I do not want to include any jQuery library.
The problem arises when I have to include the many questions that I have prepared for the page. More than 50, so I have to repeat the inline javascript in each link. Obviously with completely different questions in each case.
Is there anyway to group those events in a single function within the js file?
You shouldn’t be jumbling the JavaScript and HTML together in the first place.
Put event listeners (or move the event handlers) with the rest of the JavaScript at the bottom of the page.
You can probably use just one event listener that listens for clicks on the whole page then works out what was clicked on in order to decide on which id to process.
Easiest to give those links a shared class like ‘scroll-link’ or have some other way to select them. The trick is to use event delegation to capture clicks on all of those links with the one event listener. jQuery makes this simple:
$(document).on('click', '.scroll-link', function(event) {
var $el = $(event.target).closest('a');
smoothScroll($el.attr('href')[0]);
})