1

I have a list of items. When one is clicked, I use javascript to show a dropdown of more information.

The javascript works for the initial items, but when I dynamically load new items on this page using ajax, it stops.

At the moment, the Javascript is placed in the footer. I've tried placing it in different places in the code but to no avail. No errors show up in the console either.

I'm following the w3schools accordion tutorial here (https://www.w3schools.com/howto/howto_js_accordion.asp), and I'm using infinte scroll from Meta Fizzy (https://infinite-scroll.com/)

HTML

<ul class="item-listings">
<li class="item">
<button class="accordion">Section 1</button>
<div class="panel">
  <p>Lorem ipsum...</p>
</div>
</li>

Javascript

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    this.parentNode.classList.toggle("active");

    var panel = this.nextElementSibling;
    if (panel.style.maxHeight){
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  });
}

Ajax

<script>
jQuery(function(a){a("ul.item-listings").infiniteScroll({path:".next",append:"li.item",button:".view-more-button",scrollThreshold:!1,loadOnScroll:!1,hideNav:".pagination",history:!1,status:".page-load-status",checkLastPage:!0});var b=a(".view-more-button");a=a("ul.item-listings");var c=!1;a.on("request.infiniteScroll",function(a,c){b.hide()});a.on("load.infiniteScroll",function(a,d,e,f){c||b.show()});a.on("last.infiniteScroll",function(a,d,e){b.hide();c=!0})});
</script>

I'm not really sure what to do. Is there a way to reload this everytime I make the ajax call, or could my javascript be changed in some way? I thought that because it used a click event listener it would be fine, but sadly not.

10
  • Are you applying event listeners to the newly downloaded items? You do not have code for that in the question so it's hard to see where your problem is. Commented Aug 17, 2019 at 15:12
  • No. I'm not sure how to do that? All the new items are structured exactly the same in html. It's just the code I have here. The html and then javascript in the footer on my webpage. Commented Aug 17, 2019 at 15:15
  • "It's just the code I have here" - Nothing in "the code" adds new elements or triggers an ajax request so this cannot be the complete relevant code -> minimal reproducible example Commented Aug 17, 2019 at 15:18
  • Ok I'll update with ajax code Commented Aug 17, 2019 at 15:19
  • 1
    No. You just need to define what you want to do on click once. If you use jQuery's .on, there is no need for a for loop. Check the example I advised above. Commented Aug 17, 2019 at 16:48

1 Answer 1

1

You add event listeners to inital items only, but not on new items after they're added.

You need event propagation, basically you attach event listener to higher element (for example window, body or container of all items) and then on that event listener you check event target's className or whatever.

Since you are using jQuery, you can use jQuery's way to do that with using .on

So here is how to do it with jQuery, if you wish I can rewrite in plain JS.

$('.accordion').on('click', function() {
  $(this).toggleClass('active');
  $(this).parent().toggleClass('active');
  const panel = $(this).next()
  if (panel.css('maxHeight')) {
    panel.css({ maxHeight: 'null'})
  } else {
    panel.css({ maxHeight: panel[0].scrollHeight + 'px' })
  } 
});

There is probably way to get scrollHeight in jquery way but I havent done jQuery for long time, just cant remember.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.