1

So I started learning ES6 and modular JS(with Webpack), and now I would like to refactor this old script for the Return to top arrow, and turn it into a ES6 style script with constructor and all. This is what I got for now, but can't figure out how to write conditional statement inside a ScrollTop class..any ideas?

I am trying to write and access the conditional logic somehow, but don't know how to implement $(window).scroll etc. into the class. Do I need a new function that takes care of this..? I want it to work the same, but write it more cleanly.

Old script:

$(window).scroll(function() {
    if ($(this).scrollTop() >= 200) {        
        $('#return-to-top').fadeIn(200);   
    } else {
        $('#return-to-top').fadeOut(200);  
    }
});

$('#return-to-top').click(function() {     
    $('body,html').animate({
        scrollTop : 0                      
    }, 300);
});

<a href="#" id="return-to-top"><i class="fa fa-chevron-up"></i></a>

New script:

import $ from 'jquery';

class ScrollTop {
    constructor() {
        this.scrollUp = $("#return-to-top");
        this.topDistance = $("#return-to-top").offset().top;
        this.events();
    }

    events() {
        this.scrollUp.click(this.returnToTop.bind(this));
    }

    returnToTop() {
        $('body,html').animate({
            topDistance: 0                   
        }, 3000);
    }
}

export default ScrollTop;
Smithy
  • 743
  • 2
  • 8
  • 26
  • When you say `can't figure out how to write conditional statement inside a ScrollTop class`, are you talking about the `$(window).scroll` event's function callback ? – maazadeeb Mar 20 '17 at 10:30
  • Yes, I am trying to write and access the conditional logic somehow, but don't know how to implement $(window).scroll etc. into the class. Do I need a new function that takes care of this..? I want it to work the same, but write it more cleanly – Smithy Mar 20 '17 at 10:38
  • 1
    Your old script is ES6 already? And why do you want to introduce multiple instances here? – Bergi Mar 20 '17 at 16:16

2 Answers2

1

Actually,there is no need to define a class.Maybe you should think about what is object-oriented programming.The following way seems to be enough

import $ from 'jquery';
{
    let timer;
    $(window).scroll(function() {
        clearTimeout(timer);
        timer = setTimeout(function () {
            if ($(this).scrollTop() >= 200) {
                $('#return-to-top').fadeIn(200);
            } else {
                $('#return-to-top').fadeOut(200);
            }
        }, 30)

    });

    $('#return-to-top').click(function() {
        $('body,html').animate({
            scrollTop : 0
        }, 300);
    });
}


<a href="#" id="return-to-top"><i class="fa fa-chevron-up"></i></a>
Deng Xuening
  • 140
  • 10
  • given this is a module (implied by use of `import`), I’m not sure how useful the enclosing block statement is here, as module scope by definition is not global scope — but +1 for suggesting that a class declaration would be pointless overcomplication – Semicolon Mar 21 '17 at 06:24
0

I feel what you are asking for can be done in many ways and there might be no correct solution. But here is one way

import $ from 'jquery';

class ScrollTop {

    // Accepting a jQuery selector string to make it generic
    constructor(returnToTopSelector) { 
        this._scrollUp = $(returnToTopSelector);
        if (this._scrollUp.length) {
            this._topDistance = this._scrollUp.offset().top;
        }
    }

    setupEvents() {
        if (this._scrollUp.length) {
            this._scrollUp.click(this._returnToTop.bind(this));
            this._fadeArrow();
        }
    }

    _returnToTop() {
        $('body,html').animate({
            topDistance: 0                   
        }, 3000);
    }

    _fadeArrow() {
        const self = this;
        $(window).scroll(function() {
            if ($(this).scrollTop() >= 200) {
                self._scrollUp.fadeIn(200);   
            } else {
                self._scrollUp.fadeOut(200);  
            }
        });
    }
}

export default ScrollTop;

And I would use it this way, wherever required

import ScrollTop from 'ScrollTop'

let scrollTop = new ScrollTop("#return-to-top");
scrollTop.setupEvents();

Note the use of an underscore prefix for _returnToTop and _fadeArrow, which is supposed to indicate that these are private methods. Of course, this is just syntactic sugar. See this for more on private properties/methods in ES6

Community
  • 1
  • 1
maazadeeb
  • 5,082
  • 2
  • 24
  • 34