Elliot
Elliot

Reputation: 21

How to run the same function for different IDs separately

I'm trying to animate multiple progress/loading bars. The code below works how I want it to and I could just copy and paste then replace the ID name but that seems unnecessarily long. What's an efficient way to use my jquery code with different types of IDs (eg: #bar-x, #bar-y, #bar-z)? I've tried separating with commas like below

$(function() {
  var $stat = $('#bar-x, #bar-y, #bar-z');

  $stat.waypoint(function() {
    $stat.css({
    animation: "loading 1s linear",
    opacity: "1"
    });
  }, { offset: '95%' });
});

but then it runs all the animations at the same time when the first object reaches the requirement instead of when each individual object reaches the said requirement.

Upvotes: 2

Views: 103

Answers (4)

Tyler Roper
Tyler Roper

Reputation: 21672

It seems that the other answers aren't acknowledging the queue-ing aspect of your question so I figured I'd touch on that. In such a case, you could loop through the elements and attach the animation one second apart to each one.

Using the code below, all of the setTimeout()s will be instantiated at the same time, however the first will be for 0ms, the second 1000ms, the third 2000ms, so on and so forth.

var $stat = $('.bar');  //add class "bar" to each item you want to be included
var msDelay = 1000;

$stat.each(function(index) {
  setTimeout(() => loadNext($(this)), msDelay * index);
});

function loadNext($elem) {
  $elem.waypoint(function() {
    $elem.css({
      animation: "loading 1s linear",
      opacity: "1"
    });
  }, {
    offset: '95%'
  });
};

Demo

var $stat = $('.bar');
var msDelay = 1000;

$stat.each(function(index) {
  setTimeout(() => loadNext($(this)), msDelay * index);
});

function loadNext($elem) {
  $elem.css({ opacity: "1" });
};
.bar {
  opacity: 0;
  padding: 20px;
  margin: 5px;
  background-color: red;
  transition: opacity 1s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>

Upvotes: 1

Damian Pokorski
Damian Pokorski

Reputation: 91

You could always just wrap it in a function and use it like this

function myAnimation(selector){
  selector.waypoint(function() {
    selector.css({
      animation: "loading 1s linear",
      opacity: "1"
    });
  }, { offset: '95%' });
}

myAnimation($('#bar-y'));

This way you'd be able to call on your animation with any kind of selector repeatedly and re-usable fashion.

I'd suggest reading up on some functional programming.

Upvotes: 2

Senthil Narayanan
Senthil Narayanan

Reputation: 25

var divId = "#bar-x";


function animate (var divId)
{

 var $stat = $(divId);

  $stat.waypoint(function() {
    $stat.css({
    animation: "loading 1s linear",
    opacity: "1"
    });
  }, { offset: '95%' });

}

Upvotes: -2

Maverick976
Maverick976

Reputation: 538

After looking at Waypoints, it seems your issue comes from using the $stat object inside your callback function:

...
    $stat.css({
    animation: "loading 1s linear",
    opacity: "1"
    });
...

When the requirement for one of the waypoints is reached, it will call your .css animation on ALL of the elements that $stat contains. What you need is to make it a bit more dynamic and use this.element in place of $stat (or similar, depending on the version of Waypoints you're using).

Upvotes: 1

Related Questions