Grouping events

Hi.

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?

Thanks very much.

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.

This does not work (sorry, I am a newbie). It seems to be valid syntactically, but it does not work.

 document.addEventListener("click", function(event){
 if (event.target.className == "this-is-the-class"){
 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);
}
    }
}, false);

And the link:

<a class="this-is-the-class" href="#the-link" rel="nofollow">This is the link</a></li>

Would the technique in this article be more appropriate.

http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/

Using jQuery you go from a convoluted mess of code to a few simple lines…

Yes, but please consider the fact that I need the hash in the url to change when I click on the link, and that jQuery does not change it.

There are many of them:

https://css-tricks.com/examples/SmoothPageScroll/
http://www.sycha.com/jquery-smooth-scrolling-internal-anchor-links
http://plnkr.co/edit/jdVlxGi16Bq7TToV0oMJ?p=preview

But I need the hashes in the URLs.

Please, could someone tell where is the error in the script above?

Ok. Problem solved by using this jQuery script:

Anyway, I would appreciate some help to solve the first problem. Just for the sake of not leaving it like this.

Is this the problem you’re referring to?

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]);
})

https://davidwalsh.name/event-delegate explains how event delegation works and how to do it without jquery if you’re interested.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.