This should be fairly simple, but I seem to be missing something. I’m working on a little project in which the code that I’m writing aims to do a few things across the document. Here’s the HTML code that I want to apply my script’s actions to:
<div class="entry">
<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>
<p>One more...</p>
<div class="bttn"><a href="#">Click for More</a></div>
</div>
This template (that is, several p elements and one div with the class “bttn” inside a wrapper div with the class “entry”) is repeated multiple times across the document. Users add content to the paragraphs and eventually publish it to the site. And here’s what I wish to do in my .js file:
- Count all p elements inside the div elements with the class
“entry”. - Throughout the entire document, if there are more than two p elements inside each div classed “entry”, I want to leave the first two untouched and move the rest to a new div element with the class “slider”. This new element would be placed after the “Click for More” button.
- Add the class “show” to the already existent div element classed “bttn”, but only to those that belong to the classes “entry” that contained more than two paragraphs and were moved to the new div with the class “slider”. The new button would look like this: div class=”bttn slider” (plus the anchor tag and everything else as shown in the template).
So basically, if the user who published the content added more than two paragraphs to the HTML template, when the doc is ready I want the script to take the other paragraphs, move them to a new div element, and add a new class to the button. In the end when the “Click for More” button is clicked, the extra paragraphs that were removed and inserted afterwards will fade in nicely (since I’ll keep them hidden under the button once I’ve re-inserted them). Here’s what I’ve done so far:
$('.entry').each(function () {
$counter = $('.entry p').length;
if ($counter > 2) {
$removeExtra = $(this).find('p').not(':eq(1)').not(':eq(0)').detach();
$(this).find('.bttn').after(function () {
return '<div class="slider">' + $removeExtra.html() + '</div>';
}).addClass('show');
}
});
Issues:
- We all know that the html() method will only return the first set
of matched elements, so on button click I only get the first
paragraph that was removed from each class “entry”, and I need to get
back all detached paragraphs that I stored in the variable
$removeExtra. - Every div element with the class “bttn” is getting the new class “show”, and I only want this to happen to those that belong to the classes “entry” that saw some extra paragraphs removed. The div class=”entry” elements that had two paragraphs from the beginning should see no modification in the button’s class.
Would greatly appreciate any help with this. Thanks in advance!
This line:
Is finding all paragraphs within any “.entry” div, when you want paragraphs just within the current “.entry” div. Also you don’t need to use the callback-function syntax with
.after()since you’re using it to add after only one element at a time.Try this instead:
I’ve used the
.append()method rather than.after()since.append()will automatically add them after the last child of the element you’re appending to. You don’t need to detach the paragraphs before appending them to the new div because.append()will move them (at least, it will move them when there is only one target element – as is the case here).I’ve used
.slice()rather than your.not(':eq(1)').not(':eq(0)').Note that you should declare variables with
varor they become globals.