最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery .focus() causes page to jump - Stack Overflow

programmeradmin3浏览0评论

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?

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?

Share Improve this question asked Sep 10, 2012 at 0:21 kennysongkennysong 2,1347 gold badges25 silver badges40 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 14

"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 pletes.

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

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

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

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

If you found this question like me, you were probably looking for a CSS related issue coupled with the js focus() and you might think you're out of luck. Well, think again - the good news is that there IS a way to have a callback when a CSS animation or transition ends and then fire your event.

You can make use of jQuery's one method and use either webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend for transitions or webkitAnimationEnd oanimationend msAnimationEnd animationend for animations.

An example:

JS:

var myButton = $('#button'),
   myBox = $('#box');
    myButton.click(function () { 
    myBox.addClass('change-size');
    myBox.one('webkitAnimationEnd oanimationend msAnimationEnd animationend',   
    function(e) {
    // code to execute after animation ends
    myBox.removeClass('change-size');
    });

});

CSS:

.box {
   width: 100px;
   height: 100px;
   background: hotpink;
}

@keyframes growBox {
    to {
        width: 300px;
        height: 200px;
    }
}

.change-size {
    animation: growBox 3s linear 0s 1 normal;
}

The solution is not mine, I just found it after a couple of wasted hours, and I'm posting it in case you find this question first.

Source: http://blog.teamtreehouse./using-jquery-to-detect-when-css3-animations-and-transitions-end

发布评论

评论列表(0)

  1. 暂无评论