Q:

jQuery seems to run on only one instance

I need multiple countdown timers for multiple dates on the same page. I want to run the script on all the elements having class="cd". If you check the JSFiddle below, you'll see only one innerHTML is set:
https://jsfiddle.net/3924cofL/1/
I managed to get this far:

$(document).ready(function() {
  $(".cd").each(function(index, obj) {
    var countDownDate = new Date($(this).attr('value'));
    $id = this.id;

    // Update the count down every 1 second
    var x = setInterval(function() {

      // Get todays date and time
      var now = new Date().getTime();

      // Find the distance between now an the count down date
      var distance = countDownDate - now;

      // Time calculations for days, hours, minutes and seconds
      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      // Output the result in an element with id="demo"
      document.getElementById($id).innerHTML = days + "d " + hours + "h " +
        minutes + "m " + seconds + "s ";

      // If the count down is over, write some text 
      if (distance < 0) {
        clearInterval(x);
        document.getElementById($id).innerHTML = "EXPIRED";
      }
    }, 1000);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id="demo" class="cd" value="2018-06-10 18:00:00"></p>
<p id="demo2" class="cd" value="2018-06-11 18:00:00"></p>

A:

Your $id field is global, so it contains only the last id after the each() is finished. You need to change it be a local field:

$(document).ready(function(){
$(".cd").each(function (index, obj) {
    var countDownDate = new Date($(this).attr('value'));
    var $id = this.id; // <- should be local

    // Update the count down every 1 second
    var x = setInterval(function() {

        // Get todays date and time
        var now = new Date().getTime();

        // Find the distance between now an the count down date
        var distance = countDownDate - now;

        // Time calculations for days, hours, minutes and seconds
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        // Output the result in an element with id="demo"
        document.getElementById($id).innerHTML = days + "d " + hours + "h "
        + minutes + "m " + seconds + "s ";

        // If the count down is over, write some text 
        if (distance < 0) {
            clearInterval(x);
            document.getElementById($id).innerHTML = "EXPIRED";
        }
    }, 1000);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="demo" class="cd" value="2018-06-10 18:00:00"></p>
<p id="demo2" class="cd" value="2018-06-11 18:00:00"></p>

UPDATE 
As pointed out in other answers, you can also pass the $id as a parameter to the setInterval(), which is a preferable way, but IE 9 and earlier do not support this syntax. Check MDN for more info.

A:

It is just that the setInterval() function is an async function.
Which is why if you want to use variables that are outside the function you need to pass them.
Here is an working example

$(document).ready(function() {
  $(".cd").each(function(index, obj) {
    var countDownDate = new Date($(obj).attr('value'));
    $id = obj.id;

    var x = setInterval(function($id) {
      var now = new Date().getTime();
      var distance = countDownDate - now;

      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      document.getElementById($id).innerHTML = days + "d " + hours + "h " +
        minutes + "m " + seconds + "s ";

      if (distance < 0) {
        clearInterval(x);
        document.getElementById($id).innerHTML = "EXPIRED";
      }
    }, 1000, $id);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id="demo" class="cd" value="2018-06-10 18:00:00"></p>
<p id="demo2" class="cd" value="2018-06-11 18:00:00"></p>

But to be honest there is no reason to do it.
Why? Because you get the id from an element just to get this element by id. That's pointless. It's like I would ask Hey John, what's your name?
Here is a solution without unnecessary id variable

$(document).ready(function() {
  $(".cd").each(function(index, obj) {
    var countDownDate = new Date(obj.getAttribute('value'));

    var x = setInterval(function() {
      var now = new Date().getTime();
      var distance = countDownDate - now;

      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      obj.innerHTML = days + "d " + hours + "h " +
        minutes + "m " + seconds + "s ";

      if (distance < 0) {
        clearInterval(x);
        obj.innerHTML = "EXPIRED";
      }
    }, 1000);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id="demo" class="cd" value="2018-06-10 18:00:00"></p>
<p id="demo2" class="cd" value="2018-06-11 18:00:00"></p>

