Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spinning icons strange behavior on IE

Using Font Awesome, this creates a spinning icon:

<span class="fa fa-spinner fa-spin"></span>

When toggling the fa-spin class using JQuery on several icons like this, the behavior differs in different browsers: it works as expected under Chrome and FireFox while only the first occurence is handled correctly under IE or Edge.

For instance, with the following HTML:

<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>
<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>

with this simple JQuery code:

$(function () {
  setInterval(function() {
    $('span').toggleClass('fa-spin');
  }, 2000);
});

only the first icon is toggling between spinning and staying still while the other icons are always spinning.

Demo here: http://codepen.io/anon/pen/qOWxRg

How can I fix this so that the behavior is the same with all modern browsers?


Edit

The same behavior can be seen when the class is removed only, like this:

$('#icon').addClass('fa-spin');
setTimeout(function() {
  $('#icon').removeClass('fa-spin');
  $('#icon').height();
}, 2000);
like image 252
Yannick Blondeau Avatar asked Aug 28 '15 07:08

Yannick Blondeau


3 Answers

The final solution for me was to force the transform CSS value after removing the class.

Something like this:

$('#icon').addClass('fa-spin');
setTimeout(function() {
  $('#icon').removeClass('fa-spin');
  $('#icon').css('transform', 'none');
}, 2000);

Original answer

A workaround can be found on this Github thread: Icon won't stop spinning on Internet Explorer 11

The workaround (for IE) is to read the element's height after removing (or toggling) the fa-spin CSS class:

$('#icon').addClass('fa-spin');
setTimeout(function() {
  $('#icon').removeClass('fa-spin');
  $('#icon').height();
}, 2000);

Under Edge, you will have to set the element's height as just reading it is not enough. Something like this works:

$('#icon').addClass('fa-spin');
setTimeout(function() {
  $('#icon').removeClass('fa-spin');
  $('#icon').height($('#icon').height());
}, 2000);

As in Grzegorz's answer, this workaround can be applied under selected browsers only.

like image 177
Yannick Blondeau Avatar answered Oct 17 '22 06:10

Yannick Blondeau


Inspired by the accepted answer, I managed to solve it by resetting animation in CSS. And thus leaving javascript out of it.

.fa {
    animation: none;
}

But make sure that it don't override the fa-spin animation, since it will stop everything from spinning. If you're using a pre-compiler you could use something like:

.fa {
    &:not(.fa-spin) {
        animation: none;
   }
}

$(function () {
  setInterval(function() {
    $('span').toggleClass('fa-spin');
  }, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
      .fa {
        animation: none;
    }
</style>

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>

<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>
<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>
<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>
<span class="fa fa-spinner fa-spin"></span>
<span class="fa fa-refresh"></span>
like image 44
smoksnes Avatar answered Oct 17 '22 05:10

smoksnes


I don't have idea why IE have issue with toggle spin class but You can try this after every toggle:

 if(detectIE())
 {
    var $parent = $element.parent();
    var $newElement = $element.clone();
    $element.remove();
    $parent.append($newElement);
 }


function detectIE() {
   var ua = window.navigator.userAgent;

   var msie = ua.indexOf('MSIE ');
   if (msie > 0) {
     return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
   }

   var trident = ua.indexOf('Trident/');
   if (trident > 0) {
      var rv = ua.indexOf('rv:');
    return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
   }

   var edge = ua.indexOf('Edge/');
   if (edge > 0) {
      return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
   }

   return false;
}
like image 38
Grzegorz Zalewski Avatar answered Oct 17 '22 06:10

Grzegorz Zalewski