houstonaspen
houstonaspen

Reputation: 65

Run Javascript function only on a particular item with same class name

Without using jQuery, how can I run a function only on one item that has the same class names as the other items?

I have a WordPress loop with each item has a button to run a function on an image in the div.

Here is the loop item that repeats 10 times on the page:

 <li id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
     <div class="block bg-white relative mt-7 work__image-wrap">
       <a href='<?php echo types_render_field("website-url"); ?>' target="_blank">
        <?php echo '<img class="item absolute pin-t w-full h-auto pin-l" src="'. $workitem .'" alt="'. the_title() .'"/>';?>
       </a>
      </div>
       <div class="button-wrap">
        <button id="portScroll">Scroll Down</button>
       </div>
       <div class="p-2">
        <h3 class="text-black font-bold pt-4 pb-2"><a class="text-black font-bold" href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
       </div>
    </li>

When the user clicks the button the function changes the CSS so that it scrolls up.

How do I run the function only on the item in the loop?

Here is my JS to run the function. It works fine on the first loop item but not the others.

function scrollDown() {
    var portImg = document.getElementById('item');
    var height = portImg.clientHeight;
    console.log(height);
    var pos = 0;
    var id = setInterval(frame, 5);

    function frame() {
        if (pos == height) {
            clearInterval(id);
        } else {
            pos--;
            portImg.style.top = pos + 'px';
        }
    }
}

Upvotes: 0

Views: 596

Answers (2)

jaredrethman
jaredrethman

Reputation: 511

This is what I would do (Simplified of course):

(function(){
  const posts = document.getElementsByClassName('post');
  for(let i = 0, m = posts.length; i < m; i++){
    const buttonElement = posts[i].getElementsByTagName("BUTTON")[0];
    buttonElement.addEventListener('click', handleButton);
  }
  function handleButton(e){
    scrollDown(e.target.dataset.postId);
  }
  function scrollDown(item) {
    var portImg = document.getElementById('post-image-' + item);
    console.log(portImg);
    var height = portImg.clientHeight;
    var pos = 0;
    var id = setInterval(frame, 5);

    function frame() {
        if (pos == height) {
            clearInterval(id);
        } else {
            pos--;
            portImg.style.top = pos + 'px';
        }
    }
}
})();
<div class="post">
  <img id="post-image-199">
  <button data-post-id="199">
    Click Me
  </button>
</div>
<div class="post">
  <img id="post-image-195">
  <button data-post-id="195">
    Click Me
  </button>
</div>
<div class="post">
  <img id="post-image-198">
  <button data-post-id="198">
    Click Me
  </button>
</div>

Upvotes: 0

trincot
trincot

Reputation: 350310

Replace the button's id attribute with a class:

<button class="portScroll">Scroll Down</button>

Define the button click handlers like this:

for (const button of document.querySelectorAll('button.portScroll')) {
    button.addEventListener("click", scrollDown);
}

In the function scrollDown get the image as follows:

var portImg = this.parentNode.parentNode.querySelector('img.item');

Or, alternatively:

var portImg = this.closest('li').querySelector('img.item');

Upvotes: 1

Related Questions