I am trying to replace the content of a div
when user hovers on it. I have created two div
‘s. The foreground
div
is the default and on hover action I want to hide the foreground
and show background
div
.
$('.background').hide();
$(".card-text").mouseenter(function() {
console.log("enter");
$(this).next('.foreground').fadeOut();
$(this).next('.background').fadeIn();
});
$(".card-text").mouseleave(function() {
console.log("leave");
$(this).next('.foreground').fadeIn();
$(this).next('.background').fadeOut();
});
.card-text{
background-color: #d7f1f5;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-text">
<div class="foreground">
<p>MyTitle 1</p>
<p>Bla bla bla 1</p>
</div>
<div class="background">
<p>Hoveerr 1</p>
</div>
</div>
<div style="background-color: black; padding: 5px; margin:50px 0px;"></div>
<div class="card-text">
<div class="foreground">
<p>MyTitle2 </p>
<p>Bla bla bla 2</p>
</div>
<div class="background">
<p>Hoveerr 2</p>
</div>
</div>
However, nothing happens… What am I missing here?
Advertisement
Answer
The issue is because you’re using next()
, which is looking for siblings, instead of find()
which looks for children.
Note in the example below that I also added calls to stop()
so that the flickering, which occurs when the event is called multiple times as the DOM updates, is avoided.
$(".card-text").on('mouseenter', function() {
$(this).find('.foreground').stop(true).fadeOut();
$(this).find('.background').stop(true).fadeIn();
});
$(".card-text").on('mouseleave', function() {
$(this).find('.foreground').stop(true).fadeIn();
$(this).find('.background').stop(true).fadeOut();
});
.background { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-text">
<div class="foreground">
<p>MyTitle 1</p>
<p>Bla bla bla 1</p>
</div>
<div class="background">
<p>Hoveerr 1</p>
</div>
</div>
<div style="background-color: black; padding: 5px;"></div>
<div class="card-text">
<div class="foreground">
<p>MyTitle2 </p>
<p>Bla bla bla 2</p>
</div>
<div class="background">
<p>Hoveerr 2</p>
</div>
</div>
However it’s worth noting that you should use CSS where possible as it performs much better than JS. To do this you can hook :hover
states to the .card-text
and transition
the child elements based on their opacity
. Try this:
.card-text {
display: grid;
}
.card-text div {
transition: opacity 0.4s;
grid-column: 1;
grid-row: 1;
}
.foreground { opacity: 1; }
.background { opacity: 0; }
.card-text:hover .foreground { opacity: 0; }
.card-text:hover .background { opacity: 1; }
<div class="card-text">
<div class="foreground">
<p>MyTitle 1</p>
<p>Bla bla bla 1</p>
</div>
<div class="background">
<p>Hoveerr 1</p>
</div>
</div>
<div style="background-color: black; padding: 5px;"></div>
<div class="card-text">
<div class="foreground">
<p>MyTitle2 </p>
<p>Bla bla bla 2</p>
</div>
<div class="background">
<p>Hoveerr 2</p>
</div>
</div>