waypoints icon indicating copy to clipboard operation
waypoints copied to clipboard

Refreshing inside handler triggers waypoint.

Open tontonsb opened this issue 8 years ago • 6 comments

When triggered, my handler inserts element before the waypoint. As the waypoint is now lower, I have to recalculate position by calling refreshAll(). This, however fires the handler again.

Here is an example. Just open console, start to scroll and witness infinite amount of 'tick' logging down.

<!doctype html>
<html>
<head>
    <title></title>
</head>
<body>
    <div class="last"></div>

    <script src="../js/jquery-3.1.0.min.js"></script>
    <script src="../js/jquery.waypoints.min.js"></script>

    <script>
        $(function() {
            var anchor = $('.last');
            anchor.waypoint(
                function(direction) 
                {
                    newDiv = '<div style="display: block; height:2500px"></div>';
                    $(newDiv).insertBefore(anchor);
                    console.log("tick");
                    Waypoint.refreshAll();
                }, 
                {offset: '100%'}
            );
        });
    </script>
</body>
</html>

I though maybe it manages to fire before the element is added and waypoint is still on screen and put the refreshAll() inside setTimeout(), however this only caused a delay between the ticks.

Same problem has been reported on stackexchange: http://stackoverflow.com/questions/32865274/prevent-jquery-waypoints-firing-twice-or-multiple-times

tontonsb avatar Aug 24 '16 10:08 tontonsb

@tontonsb Instead of console.log('tick'), try console.log(direction). It should make the issue more apparent.

Your insert and refresh are triggering the waypoint in the up direction and you don't want to do anything in the up direction. If you use an if statement to ignore up direction triggers, I think you'll have what you're looking for.

imakewebthings avatar Sep 03 '16 06:09 imakewebthings

hey @imakewebthings, first off thanks so much for writing this plugin! It's really amazing I've used it countless times to great effect.

I'm having an issue and this was the closest issue I could find. When I run Waypoint.refreshAll() from inside a waypoint handler I get "Uncaught RangeError: Maximum call stack size exceeded". I'm triggering a height change on an element when the waypoint is hit, and so I need to refresh the waypoints on the page because the overall height of the wrapper has changed on this waypoint trigger.

Here is my code, please lmk if there is a way I can update it to get the desired result:

		var rubyWaypoint = new Waypoint({
		  element: document.getElementById(rubyId),
		  handler: function(direction) {
			$(this.element).css({
				'opacity' : '1',
				'visibility' : 'visible',
				'height' : newHeight
			});
			
			$(this.element).children('iframe').css('height', newHeight);

			Waypoint.refreshAll();

		  },
		  offset: '50%'
		});

ghost avatar Dec 20 '16 21:12 ghost

@b3smith13 I am experiencing a similiar behaviour when trying to enable a waypoint out of a handler of another waypoint.

I created a bugticket for it: https://github.com/imakewebthings/waypoints/issues/558

I have also found a work around which works for my case, see my ticket.

janwidmer avatar Mar 28 '17 10:03 janwidmer

Hey all,

I just wanted to hint, that instead of calling Waypoint.refreshAll() and trigger an infinite loop, you might call

Waypoint.disableAll();
Waypoint.enableAll();

to achieve similar affect.

gpluta avatar May 08 '17 10:05 gpluta

so, is it OK to use refreshAll() within the handler function? because I get a Uncaught RangeError: Maximum call stack size exceeded.

pirco avatar Sep 30 '17 08:09 pirco

In the end I use _.debounce to wrap Waypoint.refreshAll() Seems working for me

PikachuEXE avatar Jun 08 '18 09:06 PikachuEXE