wutadam
wutadam

Reputation: 73

How to individually select every single matching selector

I'm trying to create a script with jQuery where it finds elements with the class "timeAgo" and replace its innerHTML with how long ago the time in the create attribute was. Here's what I have:

function timeAgo(time) {
  var d = new Date();
  var diff = Math.floor((d.getTime() - time)/1000);
  if (diff >= 31536000) {
    if (Math.floor(diff/31536000) == 1) {
      return (Math.floor(diff/31536000) + " year ago");
    } else {
      return (Math.floor(diff/31536000) + " years ago");
    }
  } else if (diff >= 2592000) {
    if (Math.floor(diff/2592000) == 1) {
      return (Math.floor(diff/2592000) + " month ago");
    } else {
      return (Math.floor(diff/2592000) + " months ago");
    }
  } else if (diff >= 86400) {
    if (Math.floor(diff/86400) == 1) {
      return (Math.floor(diff/86400) + " day ago");
    } else {
      return (Math.floor(diff/86400) + " days ago");
    }
  } else if (diff >= 3600) {
    if (Math.floor(diff/3600) == 1) {
      return (Math.floor(diff/3600) + " hour ago");
    } else {
      return (Math.floor(diff/3600) + " hours ago");
    }
  } else if (diff >= 60) {
    if (Math.floor(diff/60) == 1) {
      return (Math.floor(diff/60) + " minute ago");
    } else {
      return (Math.floor(diff/60) + " minutes ago");
    }
  } else {
    if (diff == 1) {
      return (diff + " second ago");
    } else {
      return (diff + " seconds ago");
    }
  }
}
$(document).ready(function () {
  $(".timeAgo").innerHTML(timeAgo($(".timeAgo").attr("create")));
}

But whenever I run the code with multiple instances of ".timeAgo", it sets all of them to the first instance of ".timeAgo". How do I make it so that it uses each separate instance?

Upvotes: 0

Views: 76

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075735

Use each to loop through them, and $(this) within each to access each individual one:

$(".timeAgo").each(function() {
    var $el = $(el);
    $el.html(timeAgo($el.attr("create")));
});

Also note using html(), not innerHTML =. Although within the callback, there's really no need for jQuery:

$(".timeAgo").each(function() {
    this.innerHTML = timeAgo(this.getAttribute("create"));
});

In fact, you don't need jQuery at all in any modern browser (but this won't work in IE11 unless you follow my steps here to polyfill forEach):

document.querySelector(".timeAgo").forEach(function(element) {
    element.innerHTML = timeAgo(element.getAttribute("create"));
});

Side note: You appear to be creating elements with a non-standard create attribute. The WHAT-WG and W3C recommendation is not to do that, since it's always possible that attribute will be assigned standard meaning sometime in the future. Instead, use data-create (a data-* attribute) and access it via .attr("data-create"). (See my answer here for why you may or may not want to use .data("create") instead to access it.)

$(".timeAgo").each(function() {
    var $el = $(this);
    $el.html(timeAgo($el.attr("data-create")));
});

or

$(".timeAgo").each(function() {
    this.innerHTML = timeAgo(this.getAttribute("data-create"));
});

or (with polyfill for IE11 if needed)

document.querySelector(".timeAgo").forEach(function(element) {
    element.innerHTML = timeAgo(element.getAttribute("data-create"));
});

Upvotes: 2

Related Questions