Mouseenter called multiple times - javascript

I'm building a website, and for the about page, I have pictures that I want to fade to 0.5 opacity and then have text fade in on top if them. My issue is that whenever I put my mouse over one of the images, it, and the text on top of it fades in and out multiple times. Here's a link to the section of my code I'm having trouble with. The issue only occurs if you're moving your mouse over the image from outside of the containing div.
My jQuery:
$(document).ready(function() {
$('.fade').mouseenter(function() {
$(this).fadeTo(150, 0.5);
$(this).siblings().fadeIn(150);
}).mouseleave(function() {
$(this).fadeTo(150, 1);
$(this).siblings().fadeOut(150);
});
});
I've noticed that when I remove the second line of code in both mouseenter and mouseleave that it resolves the issue. I've tried mouseover, hover, stopPropogation, I've looked through all of these:
mouseenter event called twice even after stopPropagation
Mouseover and mouseleave trigger every time I move the mouse inside the given element
JS mouseenter triggered twice
JQuery mouseover function firing multiple times
How to stop toggle event from being fired multiple times on mouseenter/mouseleave?
jquery mouseover event firing twice
Jquery mouseenter() vs mouseover()
and tried everything they suggested but so far nothing has worked for me. Any ideas?

What is happening is you are fading in the elements over the image which interferes with the mouseover listener. So when you hover over the image, it begins to fade, but when the elements fade in, then it blocks the cursor from the image and triggers a mouseout event then it repeats once the elements go away.
I think the quickest way to handle this is to give the container of the image the class of fade, that way the siblings don't interfere with the mouseover listener.
You could change the markup to:
<div id="image-wrapper" >
<ul id="team-members">
<li class="tile-wrapper fade">
<div class="tile">
<img src="http://placehold.it/158x210"/>
<h3 class="bio bio-header" style="display:none;">Header</h3>
<p class="bio bio-footer" style="display:none;">Information</p>
</div>
</li>
</ul>
</div>
and the javascript to:
$(document).ready(function() {
$('.fade').mouseenter(function(ev) {
$(this).fadeTo(150, 0.5);
$(this).find('img').siblings().fadeIn(150);
}).mouseleave(function() {
$(this).fadeTo(150, 1);
$(this).find('img').siblings().fadeOut(150);
});
});
fiddle: https://jsfiddle.net/oLckb6h3/2/

The problem is the elements positioning, you are trying to overlay the images sibling, which interferes with the hover event on the image. To fix this try calling the hover state on a parent such as the "tile" class, and editing the CSS to position the text over the image using z-index and positioning.
$(document).ready(function() {
$('.tile').mouseenter(function() {
$(this).children('img').fadeTo(150, 0.5).siblings().fadeIn(150);
}).mouseleave(function() {
$(this).children('img').fadeTo(150, 1).siblings().fadeOut(150);
});
});
ul {
list-style-type:none;
}
.bio {
padding:15px;
}
.bio-header {
margin-top:-150px;
}
.tile { display: inline-block;}
.tile > img { z-index: 0; position: relative; }
.tile > .bio { z-index: 1; position: relative; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-wrapper">
<ul id="team-members">
<li class="tile-wrapper">
<div class="tile">
<img src="http://placehold.it/158x210" class="fade" />
<h3 class="bio bio-header" style="display:none;">Header</h3>
<p class="bio bio-footer" style="display:none;">Information</p>
</div>
</li>
</ul>
</div>

Related

Display <div> when hovering over another div and its children

I have a HTML div and inside it has children.
I have a jQuery mouseover event attached to the div. Upon mouseover, I display another div and on mouseout, I hide it.
However when I mouseover the "premiumlink" div, all works well, but when I move my mouse over a child of the div, the div that is conditionally displayed hides, but then jQuery figures out that the parent div is still being hovered over, so it shows it again. Then if I move my cursor back to the parent div, the div is hidden then shown again.
How can I have the mouseover and mouseout apply to all children and not this jumpy state?
Here is my HTML
<div class="platinumlevel" id="premiumlink">
<h1>
<img src="~/Content/Images/colorworld.png" alt="Logo" class="eventimage" />
Company Name
</h1>
<div id="demopreview" style="display: none;">
I should be displayed when "premiumlink" and all it's children are mouseovered
</div>
</div>
JS
$("#premiumlink").mouseover(function () {
$('#demopreview').show(1000);
}).mouseout(function () {
$('#demopreview').hide(1000);
});
Change your event from mouseover to mouseenter en mouseout to mouseleave. These work way better and in pretty much all the major browsers.
MDN Documentation on support
This is the code you'll need:
$("#premiumlink").mouseenter(function () {
$('#demopreview').show(1000);
}).mouseleave(function () {
$('#demopreview').hide(1000);
});
If you don't want to use JavaScript and jQuery for this, the same can be done with CSS:
#demopreview {
display: block
transition: all 1s linear;
}
#premiumlink:hover #demopreview {
display: block
}
As Douwe de Haan says, you should use mouseenter and mouseleave instead of mouseover and mouseout respectively.
$('#premiumlink').on('mouseenter', function(e) {
$('#demopreview').show(100);
});
$('#premiumlink').on('mouseleave', function(e) {
$('#demopreview').hide(100);
});

Make element appear and follow mouse in div and disappear when mouse leave div

I want my element to appear when the mouse enters a div, then follow the mouse and disappear once I leave the div.
I've mashed together the following code.
HTML:
<div id='box' class="box">
<img id="image" src="download.jpeg"/>
</div>
CSS:
#image {
position:absolute;
display: none;
}
JS:
$(document).mousemove(function(e){
$("#image").css({
left:e.pageX,
top:e.pageY
});
});
$('.box').mouseenter(_=> {
$('#image').show();
});
$('.box').mouseleave(_=> {
$('#image').hide();
});
DEMO
The intended functionality is inconsistent but seems to work if the mouse leaves the div quickly.
The img is inside of the box. When you hover and the image comes under your cursor, you're ALWAYS inside the box (since that's where the image is inside of the DOM structure).
So modifying your DOM as such:
<div id='box' class="box"></div>
<img id="image" src="https://i5.walmartimages.ca/images/Large/580/6_r/875806_R.jpg"/>
And then modify your CSS to include:
#image {
pointer-events: none;
}
Should accomplish what you're looking for. Here is a Fiddle with the modified code, too.

How do I assign a variable only when an element is hovered in AngularJS?

I have a bunch of divs that can be hovered.
<div ng-controller="HoverController as hover">
<div class="hoverable" data-number="1"></div>
<div class="hoverable" data-number="2"></div>
<div class="hoverable" data-number="3"></div>
</div>
What I'd like to do is, when each .hoverable div is hovered, set the value of hover.hoveredNumber to the data-number attribute of the hovered element.
There must also be a condition where no element is hovered, and the value of hover.hoveredNumber is 0.
I've considered using ng-mouseover and ng-mouseleave to manually trigger mouseover and mouseleave events for each of the hoverable divs, and from there, determine which element is hovered.
My issue is that each hoverable div also has a :hover style in the CSS. I understand that :hover is very reliable, but I don't trust the two separate mouse-detecting events to be as reliable, particularly if the user is moving their cursor very fast and one of the events is missed.
I expect there to be, at times, some discrepancy between which element is reflected in hover.hoveredNumber and the element that is currently displaying its :hovered style. The hoverable divs are also extremely close together and overlapping in some cases, and I'm concerned that the mouseover event of one div may fire before the mouseleave event of another, causing a discrepancy.
How can I guarantee accuracy as to which element is being hovered?
If you want it to be responsive, avoid ng-mouseover and ng-mouseleave. Those directives invoke AngularJS digest cycles with large computation overhead.
Instead use a custom directive:
angular.module("app",[])
.directive("detect",function() {
return {
link: postLink,
}
function postLink(scope,elem,attrs) {
elem.on("mouseover mouseleave", function(e) {
var $target = angular.element(e.target);
var num = $target.attr("data-number") || '0';
console.log("hover.hoveredNumber is",num);
})
}
})
.hoverable {
background-color: red;
height: 20px;
width: 30px;
text-align: center;
border-radius: 10px;
}
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<fieldset detect>
<div class="hoverable" data-number="1">1</div>
<div class="hoverable" data-number="2">2</div>
<div class="hoverable" data-number="3">3</div>
</fieldset>
</body>

Mouse events are not detecting other div which is on another div in JQuery

I am adding mouseover event. According to my HTML code, the myDiv is appearing exactly on <img>. I am detecting mouseover on both <img> and myDiv.
But what happens, when I hover a mouse on <img> its working fine and it's detecting that it's hovered on image but when I hover on myDiv without leaving <img>, it's not detecting myDiv, it's still in <img>. How can I detect myDiv without leaving img.
Below is my code
My HTML code
<style>
.myDiv{
position:absolute;
}
.hoverEffect{
border: 2px solid #0044ff;
opacity: 0.5;
}
</style>
<div class="myDiv">
<h1>Heading</h1>
</div>
<img src="myimage.jpg">
JQuery Code
$('body').mouseover(function(e) {
//e.target For Detecting div or image
$(e.target).addClass('hoverEffect');
});
$('body').mouseout(function(e) {
$(e.target).removeClass('hoverEffect');
}
In below GIF image, you can see content "WELCOME TO OUR APP" in above image. And after hovering on image, it's not detecting this content which has another div.
Updated Information
In above JQuery code, I've added the class "hoverEffect" to hovered div. The only problem is in hoverEffect class and that is opacity. When I use opacity then it's not detecting myDiv but when I remove opacity from css code then it's working fine.
Working jsfiddle link (without using opacity)
Not Working jsfiddle link (with opacity)
My question is, why it's not working when I add opacity to the class?
If it's possible to do it without removing opacity from class then how to do this?
Did You tried z-index css property to take div front of img?
.myDiv{
z-index:10;
}
You can detect every element inside body, move your mouse and see at the console. Here is an example:
$('body').mouseover(function(e) {
console.log(e.target);
});
.myDiv{
position:absolute;
background-color:violet;
}
h1 {
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myDiv">
<h1>Heading</h1>
</div>
<img src="http://qnimate.com/wp-content/uploads/2014/03/images2.jpg">

Hover over image to show buttons and don't trigger when hovering over actual buttons

I'm trying to get buttons to appear when hovering over an image. The following works:
jQuery('.show-image').mouseenter(function() {
jQuery('.the-buttons').animate({
opacity: 1
}, 1500);
}).mouseout(function() {
jQuery('.the-buttons').animate({
opacity: 0
}, 1500);
});
However, when moving from the image to the button (which is over the image), the mouseout/mouseenter is triggered, so the buttons fade out then fade back in (the buttons have the same class as the image, otherwise they just stay faded out). How can I prevent this from triggering? I've also tried the above code using jQuery's hover; same results. Here's a detail of the image showing the button with opacity 1 (because I'm over the image):
http://i.stack.imgur.com/egeVq.png
Thanks in advance for any suggestions.
The simplest solution is to put the two in the same parent div and give the parent div the show-image class.
I like to use .hover() to save a few key strokes. (alll hover does is implement .mouseenter() and .mouseleave(), but you don't have to type them out)
Additionally it's very imporant to fade $(this).find(".the-buttons") so that you only change the button in the hovered over div otherwise you would change all of the .the-buttons on the entire page! .find() just looks for descendants.
Finally, .animate() will work, but why not just use .fadeIn() and .fadeOut()?
JS:
jQuery(function() { // <== Doc ready
jQuery(".the-buttons").hide(); // Initially hide all buttons
jQuery('.show-image').hover(function() {
jQuery(this).find('.the-buttons').fadeIn(1500); // use .find() !
}, function() {
jQuery(this).find('.the-buttons').fadeOut(1500); // use .find() !
});
});
Try it out with this jsFiddle
HTML: - Something like this
<div class="show-image">
<img src="http://i.stack.imgur.com/egeVq.png" />
<input class="the-buttons" type="button" value=" Click " />
</div>​
CSS: - Something like this. Yours will likely be different.
div {
position: relative;
float:left;
margin:5px;}
div input {
position:absolute;
top:0;
left:0; }​
Put the image and the button in the same div, then put the mouseover/mouseout events on the div. Than whether your mouse is over either the button or the image, it will still be over the div.
Also I am not sure if mouseenter(...).mouseout(...) will work. I always use hover(..., ...)

Categories

Resources