Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start spinning a bootstrap font awesome icon, then make it stop with jQuery

I have the font awesome refresh icon on a webpage that I am working on.

<i class="fa fa-refresh fa-3x" id="lock-refresh"></i>

When this icon is clicked, I want it to start spinning. I've been able to accomplish this by inputting the following in my JavaScript file:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' ).

    //Below is a function that I need to run after the FA icon is clicked.
    startup();
});

I only need this icon to spin for a couple of seconds, though. I've tried to add this (below) to my JS file, but when I do the icon does not spin at all:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' );

    //Trying to remove the class after 1000 milliseconds. Not working.
    $( this ).delay(1000).removeClass( 'fa-spin' );
    startup();
});

I've also tried the following, which doesn't work as well:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' ).delay(1000).removeClass( 'fa-spin' );
    startup();
});

I've also tried the following, but when I do this the icon starts spinning but won't stop:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' );

    //Trying to use setTimeout, but doesn't seem to work either.
    setTimeout(function() { $( this ).removeClass( 'fa-spin' ); }, 1000);
    startup();
});

I've tried all of the above without my startup() function, and it produces the same results so I'm sure it is not the function.

How do I get my FA refresh icon to spin for only a second or two, then stop?

like image 355
aCarella Avatar asked Nov 14 '15 15:11

aCarella


2 Answers

You should do:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' );
    var $el = $(this);
    setTimeout(function() { $el.removeClass( 'fa-spin' ); }, 1000);
    startup();
    // Whatever here.
});

Because this was something else inside setTimeout(function(){ and was not pointing to the clicked element.

Working Fiddle

Query's CSS manipulation isn't queued, but you can make it executed inside the 'fx' queue by doing:

 $( '#lock-refresh' ).click(function() {
        $(this).addClass("fa-spin").delay(1000).queue('fx', function() { $(this).removeClass('fa-spin'); });
        startup();
        // Whatever here.
 });

Working Fiddle

like image 144
void Avatar answered Sep 24 '22 03:09

void


You can't use delay method in this case because addClass doesn't return queue interface to work with delay.

So you should indeed use setTimeout but use correct this value inside. The problem is that setTimeout will execute callback function in global object (this === window) context. So you need to provide a proper context. For this, it's convenient to use Function.prototype.bind method:

$( '#lock-refresh' ).click(function() {
    $( this ).addClass( 'fa-spin' );
    setTimeout(function() { 
        $( this ).removeClass( 'fa-spin' ); 
    }.bind(this), 1000);
    startup();
});
like image 34
dfsq Avatar answered Sep 25 '22 03:09

dfsq