Hi there, been trying to solve something for hours and really need some help now - a forum post is always my last resort!
I'm using the Infinite Scroll WordPress plugin, which uses AJAX to load the next page of posts.
It works great and it even has an area in the plugin settings to add any JavaScipt that needs to be applied to the newly loaded posts.
This has helped solve a lot of issues, however I have some simple show/hide and slide jQuery applied to something within the posts. When the new posts are loaded with AJAX, this jQuery then executes twice.
Here's the code...
So basically, the comments are hidden by default and are accessed by clicking on the .show-comments button. This works fine on the initial posts.
Then when the new posts are loaded, this works fine on the new posts, but then it runs twice on the initial posts. So when you click .show-comments, the comments will slide down and up again.
How do I stop the jQuery from running twice on the initial posts when it is called again for the new posts?
I hope that all makes sense! Any help would be massively appreciated!!
$('.show-comments').click() attaches a click handler to every element that has a class of 'show-comments' anywhere within the document. So on first run, you've loaded a few posts, then found *.show-comments and attached click handlers. On 2nd run, you now got a few new posts, but you still find all the *.show-comments elements and attach click handlers. Which means that *.show-comments within the first loaded posts now have 2 click handlers on them, and each click handler will run.
To prevent this you can add an event.stopImmediatePropagation() call to your handler (which will prevent any other handlers being run and stop bubbling of the event). Or you could unbind any existing click() handlers before binding the new one. Eg. (both)...
event.stopImmediatePropagation(); // as long as not bubbling up the DOM is ok?
An alternative is to provide some context for your selector, such that it only looks for relevant elements within the newly loaded posts. However, unless they have some unique identifying characteristic (or the plugin can tell you which they are), this may not be easy/feasible.
You may have a similar problem with the $('ol .comments').hide(); statement, I don't know, but that may be something that can be resolved with some context or additional selectors.
Thanks a lot for your help - I've made some real headway with it now!
Your method works great for the click handlers, but as you suggested, I'm still having problems with the hide stuff, as when the new JS loads after AJAX, it will then hide everything.
I've worked out a way to provide some context for the new posts. The plugin works by getting the next page and loading it at the bottom basically, the next page being domain.com?paged=2 etc.
So I used PHP GET to get the paged value and apply this as a class to the posts from each new page.
So when the posts from page 2 load, these posts will all have a class of 2 etc. (stick with me here...)
I thought I'd cracked it here, by passing this paged variable through to JS and using it in the JS to be run with each new load.
However, the new JS to be applied after AJAX seems to be called in the head of the page and if I use the PHP GET to get the paged value in the head (before the JS), it doesn't get the value. If I call it further down in the page, it gets the value but it then doesn't pass it through to the JS which is called before it.
I hope that makes sense... I know this is quite a way off the original query - but if anyone has ANY idea where I can go from here, it would be hugely appreciated!!
You may want to consider it from the other angle... Instead of trying to determine which elements haven't been processed (ie. the new ones), set something up that allows you to exclude those that have been processed? Eg...