10

So, I'd like to fire a function only once on scroll (using Scrollstop, given by a stackoverflow answer)

The problem is that I don't get to fire the function only once. I've tried different solutions ( .on(), setting a counter, setting it outside/inside the window.scrollstop function) but nothing worked.

I don't think it's difficult, but.. I didn't get to make it work so far.

Here's the plugin I'm using

  $.fn.scrollStopped = function(callback) {           
          $(this).scroll(function(){
              var self = this, $this = $(self);
              if ($this.data('scrollTimeout')) {
                clearTimeout($this.data('scrollTimeout'));
              }
              $this.data('scrollTimeout', setTimeout(callback,300,self));
          });
      };

and here's my code:

        $(window).scrollStopped(function(){
            if ($(".drawing1").withinViewport()) {      
                doNothing()
                }
            })


var doNothing = function() {
            $('#drawing1').lazylinepainter('paint');
        }

(removed the counter since it didn't work)

Live demo here

PS: the function I'd like to make happen only once is the lazyPaint. It begins when we scroll to the element but it fires once again when it ends.

Community
  • 1
  • 1
Naemy
  • 446
  • 2
  • 5
  • 17

5 Answers5

7

how about using a variable to see whether it was previously fired:

var fired = 0;
$.fn.scrollStopped = function(callback) {           
          $(this).scroll(function(){
              if(fired == 0){
                var self = this, $this = $(self);
                if ($this.data('scrollTimeout')) {
                  clearTimeout($this.data('scrollTimeout'));
                }
                $this.data('scrollTimeout', setTimeout(callback,300,self));
                fired = 1;
              }
          });
      };
AddiktedDesign
  • 512
  • 2
  • 16
7

Here's my version of having a function fire once while listening to the scroll event:

var fired = false;
window.addEventListener("scroll", function(){
  if (document.body.scrollTop >= 1000 && fired === false) {
    alert('This will happen only once');
    fired = true;
  }
}, true)
hzhu
  • 3,759
  • 5
  • 29
  • 39
4

These anwsers didn't work for me so here's my code:

        var fired = 0;
        jQuery(this).scroll(function(){
            if(fired == 0){
                alert("fired");
                fired = 1;
            }
        });
Mike
  • 1,258
  • 12
  • 12
0

How about this solution?

function scrollEvent() {
  var hT = $('#scroll-to').offset().top,
    hH = $('#scroll-to').outerHeight(),
    wH = $(window).height(),
    wS = $(this).scrollTop();
  if (wS > (hT+hH-wH)){
    console.log('H1 on the view!');
    window.removeEventListener("scroll", scrollEvent);
  }
}
window.addEventListener("scroll", scrollEvent);
  • 2
    While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – peacetype Feb 04 '18 at 16:09
0

The question is a bit old, but as it popped up first when I search for "addeventlistener scroll once", I will add this reply. There is now a { once: true } parameter to only trigger an event once.

window.addEventListener("scroll", () => {
/* your code here */
}, { once: true });
Jeremie
  • 646
  • 8
  • 24