Thom Thom - 1 year ago 106
Javascript Question

Scrolltop function running twice

I have an on change function on a select element that triggers an ajax request and response. At some point recently, it began running twice, but not the change trigger itself. Just everything inside the change function. To repeat: the change function is only triggered once, but the content of the function runs twice. This wasn't happening two weeks ago (last time I checked it) and I haven't changed any related code since then. Did just upgrade to WordPress 4.5. Here's the code (with the console log information in comments):

$('body').on('change', 'select#users_view', function()
var view = $(this).val();
console.log('triggered '+view); // this only prints ONCE
$('html, body').animate({scrollTop:0}, 250, function()
console.log('scroll top '+view); // this prints TWICE
if('status' in response)
if(response.status == 'success')
console.log('success '+view); // this prints TWICE
$.ReplaceUsersContainer(response.html, false);
else if(response.status == 'error') $.showError(response.message);
else $.showError();
else $.showError();

What on earth? The javascript file is only being loaded once. No other javascript file references this select element anywhere. The change function is only being triggered once, as the console log indicates. But for some reason the animate function is running twice.

It just occurred to me that maybe it's running twice because the selector for the animate function is
html, body
, but this has never been the case with jQuery before, and if this is what jQuery is doing now, I've got thousands of javascript files to modify.

Answer Source

Wow, thanks jQuery. Using html,body as the selector on scrollTop functions has been standard practice for a whole lot of us for a long time, and now it behaves differently, and we all have a lot of work to do. EVEN WORDPRESS CORE FILES use html,body on animate functions.

In short: the selector html,body will now cause animate functions to run twice in jQuery v1.12.3, whereas in prior versions, this was not the case.


Since Firefox needs html and Chrome, etc. need body, the way to fix this is using a debounce function.

I use this tiny plugin:

Then call my function like this:

$('html,body').animate({scrollTop:0}, 250, $.debounce(0, true, function()
    // do stuff
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download