I’m newer to Javascript and am trying to set up some cards so that when the user’s mouse enters the card div that it adds or removes a class to the button contained within.
The logic would be: when the "version-card" div detects a mouseOver it will add a "active" class with a different background color to the button within.
I’ve tried .querySelector, .querySelectorAll, and .getElementByID but it doesn’t seem to work. I’m missing something small I think but wanted help figuring out what I set up wrong. Do I need to loop something? The missing part is how to apply the class change to multiple/all of the divs and buttons, not just the first one
I’ve successfully used the code to change the color of the button, but it only is set up to change the first card’s button, not every card’s button like I want. (2nd code snippet below).
JSfiddle here: https://jsfiddle.net/rtpzeo0n/
document.querySelectorAll(".version-card").addEventListener("mouseover", mouseOver);
document.querySelectorAll(".version-card").addEventListener("mouseout", mouseOut);
function mouseOver() {
document.getElementById(".button-primary").classList.add("active");
}
function mouseOut() {
document.getElementById(".button-primary").classList.remove("active");
}
.active {
background:red!important;
}
<div class="version-card" style="padding:30px;border:2px solid black;">
<div class="card-content">
<h1>
header
</h1>
<p>
blah blah blah
</p>
<a class="button-primary" style="padding:20px; background:green;" id="button-primary">Button</a>
</div>
</div>
<div class="version-card" style="padding:30px;border:2px solid black;">
<div class="card-content">
<h1>
header
</h1>
<p>
blah blah blah
</p>
<a class="button-primary" style="padding:20px; background:green;" id="button-primary">Button</a>
</div>
</div>
<div class="version-card" style="padding:30px;border:2px solid black;">
<div class="card-content">
<h1>
header
</h1>
<p>
blah blah blah
</p>
<a class="button-primary" id="button-primary" style="padding:20px; background:green;">Button</a>
</div>
</div>
=====
Code that worked but only changed the first button, not multiple
document.querySelector(".version-card").addEventListener("mouseover", mouseOver);
document.querySelector(".version-card").addEventListener("mouseout", mouseOut);
querySelector(".version-card").classList.add('active');
function mouseOver() {
document.querySelector(".button-primary").classList.add("active");
}
function mouseOut() {
document.querySelector(".button-primary").classList.remove("active");
}
.active {
background:red!important;
}
<div class="version-card" style="padding:30px;border:2px solid black;">
<div class="card-content">
<h1>
header
</h1>
<p>
blah blah blah
</p>
<a class="button-primary" style="padding:20px; background:green;">Button</a>
</div>
</div>
2
Answers
To do what you require you can use the CSS
:hover
pseudo selector.Also note that the
!important
modifier is something you should absolutely avoid. Make your CSS selectors more descriptive to increase precedence if you’re trying to override existing styles.You would need to move your CSS to an external stylesheet for this to work in this case, which again is something you should absolutely do. JS and CSS shouldn’t be in a HTML file.
If, for whatever reason, you did want to do this in JS, although I wouldn’t suggest you do, then there’s a few issues in your JS which need to be fixed:
querySelectorall()
returns a NodeList, not a single Element, therefore you need to loop through them to attach the event handlers..button-primary
within the.version-card
that triggered the event. You can use the Event object within the arguments of the handler to get a reference to thetarget
property and selecting the child element from there.mouseenter
andmouseleave
events for this.mouseover
fires once for every pixel that the mouse moves over the element, which is overkill in this case.Just use querySelectorAll instead of querySelector