wawan Setiyawan
wawan Setiyawan

Reputation: 371

why can't $(this) be used in jquery .animate()?

i have progress bar with bootstrap , this is html :

$(".progress-bar").animate({
  width: $(this).data('width') + '%'
}, 2500);
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="alert alert-success">
  <div class="skill-name">ON PROGRESS 357/487</div>
  <div class="progress">
    <div class="progress-bar progress-bar-primary" role="progressbar" data-width="70">
    </div>
  </div>
</div>

why jquery on above not working if i used $(this).data('width') + '%' . But if i used $(".progress-bar").data('width') + '%' worked. ?thanks

Edit

If I use $(".progress-bar").data('width') + '%' It will change all .progress-bar.

Upvotes: 4

Views: 72

Answers (1)

Soviut
Soviut

Reputation: 91585

You're dealing with a scoping issue. The .animate() method only scopes this inside its complete callback. Otherwise, it's probably scoping it to the caller.

To solve this, cache your selection in a variable and use it throughout the rest of your code. Besides always maintaining the correct scope, this is technically faster since it doesn't need to re-wrap this in a jQuery object.

var progressBar = $(".progress-bar");
progressBar.animate({
  width: progressBar.data('width') + '%'
}, 2500);

If you're dealing with multiple progress bars, you can use .each() to iterate over them and apply the animation to each element while they're still in scope.

$(".progress-bar").each(function(i, item) {
  var progressBar = $(item); // $(this) would work too
  progressBar.animate({
    width: progressBar.data('width') + '%'
  }, 2500);
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="alert alert-success">
  <div class="skill-name">ON PROGRESS 357/487</div>
  <div class="progress">
    <div class="progress-bar progress-bar-primary" role="progressbar" data-width="70">
    </div>
  </div>
</div>

Upvotes: 6

Related Questions