Home > Software design >  Is it possible to use two querySelectorAll one inside the other in Javascript?
Is it possible to use two querySelectorAll one inside the other in Javascript?

Time:12-23

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 >
<div id="act-reactions" >
<div >
<div >
<div >
<a  href="#/"></a>
<p>Like</p>
</div>
<div >
<a  href="#/"></a>
<p>love</p>
</div>
<div >
<a  href="#/"></a>
<p>Haha</p>
</div>
<div >
<a  href="#/"></a>
<p>Wink</p>
</div>
<div >
<a  href="#/"></a>
<p>Wow</p>
</div>
<div >
<a  href="#/"></a>
<p>Sad</p>
</div>
<div >
<a  href="#/"></a>
<p>Angry</p>
</div>
<div >
<a  href="#/"></a>
<p>Crazy</p>
</div>
<div >
<a  href="#/"></a>
<p>Speechless</p>
</div>
<div >
<a  href="#/"></a>
<p>Grateful</p>
</div>
<div >
<a  href="#/"></a>
<p>Celebrate</p>
</div>
<div >
<a  href="#/"></a>
<p>Heartbroken</p>
</div>
<div >
<a  href="#/"></a>
<p>Evil</p>
</div>
<div >
<a  href="#/"></a>
<p>Embarassed</p>
</div>
</div>
</div>
</div>
<a id="default-like-2288" href="#/"  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!!

CodePudding user response:

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'})
    })

CodePudding user response:

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'>
             
  • Related