How add class to a div after class in jQuery? - javascript

I have a child div that needs to be added with a class using jQuery.
<div class="main-content">
<article class="post status-publish">
<div class="post-content>
<div class="vc_row wpb_row vc_row-fluid">
<div class="vc_col-sm-12 wpb_column vc_column_container ">
</div>
</div>
</div>
</article>
</div>
The jQuery code that i tried so far is this:
j('.main-content .post-content').each(function () {
j(this).after().addClass('home-inner-content');
});
This is the result that i am desiring for:
<div class="main-content">
<article class="post status-publish">
<div class="post-content>
<div class="vc_row wpb_row vc_row-fluid home-inner-content">
<div class="vc_col-sm-12 wpb_column vc_column_container ">
</div>
</div>
</div>
</article>
</div>
Any help is appreciated. Thanks

You probably want something like:
j('.main-content .post-content').each(function () {
j(this).children().first().addClass('home-inner-content');
});
.after() is for inserting content, not locating it.
But really, I don't think you need a loop. You can do:
j('.main-content .post-content > *:first-child').addClass('home-inner-content');
The first part selects the elements you want. .addClass() adds a class to each of the elements that got selected.

If I understand you correctly, next code will help.
$('.main-content .post-content>div').addClass('home-inner-content');

$('.main-content .post-content').each(function() {
$(this).children().addClass('home-inner-content');
});
body * {
padding-left: 1em;
}
body *:before {
font-family: monospace;
content: attr(class);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-content">
<article class="post status-publish">
<div class="post-content">
<div class="vc_row wpb_row vc_row-fluid">
<div class="vc_col-sm-12 wpb_column vc_column_container">
</div>
</div>
</div>
</article>
</div>

You don't need to use each function here.
j('.main-content .post-content>div').addClass('home-inner-content');

Related

Is it possible to use two querySelectorAll one inside the other in Javascript?

I am trying to create a reaction system like Facebook but there is a problem I cannot figure out. So, let's explain how my html looks like. There is a main div that contains a link element (<a></a>) which is used for the default like icon to hover and open the reactions and a div that contains the reactions. Like you can see below:
<div class="post__actions-inner">
<div id="act-reactions" class="container">
<div class="content">
<div class="emoji">
<div class="hello">
<a class="emoticon-0" href="#/"></a>
<p>Like</p>
</div>
<div class="hello">
<a class="emoticon-1" href="#/"></a>
<p>love</p>
</div>
<div class="hello">
<a class="emoticon-2" href="#/"></a>
<p>Haha</p>
</div>
<div class="hello">
<a class="emoticon-3" href="#/"></a>
<p>Wink</p>
</div>
<div class="hello">
<a class="emoticon-4" href="#/"></a>
<p>Wow</p>
</div>
<div class="hello">
<a class="emoticon-5" href="#/"></a>
<p>Sad</p>
</div>
<div class="hello">
<a class="emoticon-6" href="#/"></a>
<p>Angry</p>
</div>
<div class="hello">
<a class="emoticon-7" href="#/"></a>
<p>Crazy</p>
</div>
<div class="hello">
<a class="emoticon-8" href="#/"></a>
<p>Speechless</p>
</div>
<div class="hello">
<a class="emoticon-9" href="#/"></a>
<p>Grateful</p>
</div>
<div class="hello">
<a class="emoticon-10" href="#/"></a>
<p>Celebrate</p>
</div>
<div class="hello">
<a class="emoticon-11" href="#/"></a>
<p>Heartbroken</p>
</div>
<div class="hello">
<a class="emoticon-12" href="#/"></a>
<p>Evil</p>
</div>
<div class="hello">
<a class="emoticon-13" href="#/"></a>
<p>Embarassed</p>
</div>
</div>
</div>
</div>
<a id="default-like-2288" href="#/" class="post__action post__action--reaction reaction reaction__toggle reaction-toggle--2288 reaction-emoticon-0 js-reaction-toggle" style="display: block;" data-id="2288">
<span>Like</span>
</a>
</div>
So, what I am trying to do is to show the reactions when I hover over the default like. I tried to use two querySelectorAll one inside the other but it didn't help in this problem. This is what I tried:
document.querySelectorAll('.post__action--reaction.container').forEach(elem => elem.addEventListener("mouseenter", () => {
var container = document.querySelectorAll('.container').forEach(elem => elem.addEventListener("mouseenter", () => {
container.style.display = "block";
}));
}));
What can I do to fix this problem? Thanks in advance!!
first of all '.post__action--reaction.container' is not the correct selector. If you are trying to add event listener to your default like button, then you should be listeninig to '#default-like-2288' or just '.post__action--reaction'.
I am assuming you will have multiple default like buttons & containers. You can show and hide the .container elements using the following logic,
let defaultLike = document.querySelectorAll('.post__action--reaction')
defaultLike.forEach((like) => {
//gets the previous sibling node which is also an element.
//here, previous element sibling of the like button is #act-reactions div
let reactionContainer = like.previousElementSibling
like.addEventListener('mouseenter', () => {reactionContainer.style.display = 'block'})
like.addEventListener('mouseleave', () => {reactionContainer.style.display = 'none'})
})
I think your approach is a little over complicated. It looks like you have a consistent structure for the tags etc... so I would suggest just putting each set of like button and emoji inside of one container and using querySelectorAll() to grab each container.
You can iterate over each container and change the visibility of it's children by toggling classes.
I've included an example that I think takes a pretty simple and vanilla JS approach to this.
let likeButtons = [...document.querySelectorAll(".likeButton")];
likeButtons.forEach(lb=>{
lb.addEventListener("mouseover",()=>{
lb.children[0].classList.remove("hidden");
})
lb.addEventListener("mouseout",()=>{
lb.children[0].classList.add("hidden");
})
})
.content{
width:400px;
height:200px;
border: 1px solid gray;
position:relative;
}
.likeButton{
position:absolute;
cursor:pointer;
left:100%;
top:100%;
transform: translateX(-100%) translateY(-100%);
}
.emojiContainer{
position:absolute;
left:100%;
top:10%;
transform: translateX(-100%) translateY(-100%);
}
.hidden{
display:none;
}
<div class='content'>
<div class='likeButton'>
👍
<div class='emojiContainer hidden'>
<span>😂</span>
<span>😁</span>
<span>😍</span>
<span>😏</span>
<span>🤗</span>
</div>
</div>
</div>
<div class='content'>
<div class='likeButton'>
👍
<div class='emojiContainer hidden'>
<span>😂</span>
<span>😁</span>
<span>😍</span>
<span>😏</span>
<span>🤗</span>
</div>
</div>
</div>
<div class='content'>
<div class='likeButton'>
👍
<div class='emojiContainer hidden'>
<span>😂</span>
<span>😁</span>
<span>😍</span>
<span>😏</span>
<span>🤗</span>
</div>
</div>
</div>

Get next element with class (that's not a child or sibling)

With the press of a button, I want to toggle the class .active on the next div.bottom. These are basically accordions, but with a different structure.
Using nextElementSibling I guess won't work here to select the target element. How would one select such an element, that's neither a child nor a sibling (in plain JS)?
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
I'd do it by using closest to go up to the container .wrapper element, then querySelector to find the bottom element:
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button && button.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
Or the same thing using optional chaining (relatively new):
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button?.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
By using closest() you can traverse the DOM upwards. With this it's easy to just get the relevant .bottom and toggle the active class on this element.
document.querySelectorAll('button').forEach(button => {
button.addEventListener('click', (e) => {
e.currentTarget.closest('.wrapper').querySelector('.bottom').classList.toggle('active');
});
});
.bottom {
display: none
}
.bottom.active {
display: block
}
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle</button>
</div>
</div>
<div class="bottom">Hidden content</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle 2</button>
</div>
</div>
<div class="bottom">Hidden content 2</div>
</div>

How can I wrap inner divs that are dynamic?

I have been trying badly to wrap some divs with an outer div so that I can style them. But I'm unable to do so thus far.
I have this list div which contains some inner divs that I need to wrap. That is the inner divs which have same letters need to be bundled together. Although targeting the divs with the letters is not a good idea as they are gonna be dynamic.
This is an example of what I have been trying to achieve:
<div class="list-wrapper">
<div class="el">A</div>
<div>
<a>A</a>
</div>
</div>
<div class="list-wrapper">
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
</div>
Another example:
This is what I have tried so far:
$(list).find('div.el').each(function(idx, item) {
$(item).nextAll('div').wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div>
<a>A</a>
</div>
<div class="el">B</div>
<div>
<a>B</a>
</div>
<div class="el">C</div>
<div>
<a>C</a>
</div>
<div>
<a>C</a>
</div>
<div class="el">D</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div>
<a>D</a>
</div>
<div class="el">E</div>
<div>
<a>E</a>
</div>
</div>
To achieve your goal you can use a combination of nextUntil() within the loop, to get the div elements between each .el, and wrapAll(). You can include addBack() in there to add the current .el in the loop in to the collection to be wrapped. Try this:
$('#list').find('.el').each((i, el) => {
$(el).nextUntil('.el').addBack().wrapAll('<div class="list-wrapper"></div>')
});
.wrapper {
background-color: red;
padding: 20px;
}
.list-wrapper { border: 1px solid #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="el">A</div>
<div><a>A</a></div>
<div class="el">B</div>
<div><a>B</a></div>
<div class="el">C</div>
<div><a>C</a></div>
<div><a>C</a></div>
<div class="el">D</div>
<div><a>D</a></div>
<div><a>D</a></div>
<div><a>D</a></div>
<div class="el">E</div>
<div><a>E</a></div>
</div>
Note that $(list) was only working by proxy, as elements with an id attribute are available as properties on the document. It's much better practice to use a valid string selector.

css odd even not working with pseudo-elements

I have a container div names wrapper and it has several child divs named thumb
I want to apply css pseudo elements with the even and odd.
My codes are
<div class="wrapper">
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
</div>
And my css:
.wrapper:nth-child(even) .thumb:after{
//some codes
}
.wrapper:nth-child(odd) .thumb:after{
//some codes
}
But i am getting only odd styles.
Since the odd and even relationship is applied based on sibling index, you need to apply it on col-half as that is the repeated element.
Since your thumb element is the first child of its parent, it will only satisfy the odd selector
.wrapper .col-half:nth-child(even) .thumb:after {
content: 'x'
}
.wrapper .col-half:nth-child(odd) .thumb:after {
content: 'y'
}
<div class="wrapper">
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
<div class="col-half">
<div class="thumb">
...
</div>
</div>
</div>
You have a misunderstanding about :nth-child as it does not work as "nth child of this container" but as "am I the nth child of my parent?".
So you need to apply :nth-child(odd/even) to .col-half:
.col-half:nth-child(even) .thumb:after{
//some codes
}
.col-half:nth-child(odd) .thumb:after{
//some codes
}
The name for this selector has really caused many misunderstandings as it is too easy to misunderstand the way you did.
.col-half:nth-child(even) {
color: green;
}
.col-half:nth-child(odd) {
color: red;
}
Try like this: Demo
In your css, You are using the parent div for showing even and odd. Instead you need to use odd / even for child elements which repeats
.col-half:nth-child(even) .thumb{
background:#ccc;
}
.col-half:nth-child(odd) .thumb{
background:#f00;
}
Try This One
.wrapper .col-half:nth-child(2n) .thumb:after {
content: '';
}
.wrapper .col-half:nth-child(2n-1) .thumb:after {
content: '';
}

Selecting the h2 element based on a clicked parent

I have a div called "panel" with multiple child elements, each with a class of poster. Each poster will be a card displaying restaurant information. I want to target the h2 for whichever poster the user clicks on, irrespective of which area of the poster they click. I'm using event delegation on the panel but I'm not sure how to target the h2.
HTML:
<div class="panel">
<div class="poster">
<div class="wrapper">
<p class="time">6-7:30PM</p>
<div class="inner-wrapper">
<h2 class="restaurant-title">Restaurant A</h2>
<h3 class="deal-description">bla bla bla</h3>
</div>
</div>
</div>
<div class="poster">
<div class="wrapper">
<p class="time">2-4:30PM</p>
<div class="inner-wrapper">
<h2 class="restaurant-title">Restaurant B</h2>
<h3 class="deal-description">bla bla bla</h3>
</div>
</div>
</div>
<div class="poster">
<div class="wrapper">
<p class="time">1-5:30PM</p>
<div class="inner-wrapper">
<h2 class="restaurant-title">Restaurant C</h2>
<h3 class="deal-description">bla bla bla</h3>
</div>
</div>
</div>
</div>
JS:
var panel = document.querySelector(".panel");
panel.addEventListener("click", handleClick);
use queryselector() in javascript
function handleClick(){
var h2=this.querySelector("h2");
}
Demo
Using jquery:
$(".panel").click(function(){
var h2 = $(this).find('h2');
});
Try this :
$(document).ready(function(){
$(".poster").click(function(){
var h2 = $(this).children(".restaurant-title");
//alert(h2.context.innerText);
})
})
Example on jsfiddle: https://jsfiddle.net/ar1xawku/
Don't forget include jquery library in your code
so i figured out a solution for this, and thought i'd share:
$(".poster").click(function(){
var h2 = $(this).find('h2');
var restaurantTitle = (h2["0"].innerText);

Categories

Resources