Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .focus() causes page to jump

I have a function that should scroll a user back to a search input at the top of the page, and then place focus on it (so the cursor is blinking). For some reason, it seems to apply the focus to the search input first. This creates a very quick jump/spazzy movement of the page to the search bar, jumps back to the bottom, and then scrolls up slowly.

The Javascript:

function goToSearch(){
    $('html,body').animate({scrollTop: $('#search').offset().top},'medium');
    $('#search').focus()
}

The HTML:

<input type="text" id="search" placeholder="search">
...
<a href="#" onclick="goToSearch()">Search</a>

I've tried setting .delay() functions to no avail; it seems to always apply the .focus() first. Why is this happening?

like image 435
kennysong Avatar asked Nov 29 '25 06:11

kennysong


2 Answers

"Why is this happening?"

The animation effect is asynchronous. That is, the .animate() function returns immediately after "scheduling" the animation (so to speak) and execution continues immediately with the next statement - in your case, the .focus() statement. The actual animation will take place after the current JS completes.

Fortunately the .animate() method provides an option for you to pass a callback function that will be called when the animation is complete, so you can do the focus within that callback function:

$('html,body').animate({scrollTop: $('#search').offset().top},'medium', function(){
    $('#search').focus();
});
like image 80
nnnnnn Avatar answered Nov 30 '25 19:11

nnnnnn


You should call the focus function when the animation is complete, like so:

function goToSearch(){
    $('html,body').animate({scrollTop: $('#search').offset().top},'medium',function(){
        $('#search').focus();
    });
}
like image 39
ACJ Avatar answered Nov 30 '25 19:11

ACJ