Nested hover events, only apply to most direct hovered element - javascript

HTML:
<div class="outer">
<div class="inner">
</div>
</div>
CSS:
.outer {
outline: 1px solid green;
padding: 20px;
}
.inner {
outline: 1px solid red;
height: 50px;
}
.hover {
outline: 1px solid yellow;
}
JS:
$('.outer, .inner').on('mouseenter', function(e){
$(this).addClass('hover');
}).on('mouseleave', function(e){
$(this).removeClass('hover');
});
http://codepen.io/anon/pen/tEAiG/
Is there a way I can make it so the hover class is only applied to the directly hovered element? ie. When the mouse is inside the inner div only it is yellow, and not outer as well?

Since you are handling the hover by adding the class yourself, rather than using CSS :hover, you can stop propagation of the event in your handler when reacting to the mouseenter.
That way, if the handler is reacting to the .inner it will stopPropagation() to prevent the event from also going to the .outer
Another issue is going to be that you must have entered the outer and handled it in order to even reach the inner, so you will want to remove the hover class that must have been added to the parent node.
Demonstrated in this fiddle

A possible method could be removing the hover class from the outer div and then applying it to the inner div when the mouse is inside the inner div, since whenever you go inside the inner div, the hover class is applied on both divs.

You could do this by making a separate handler for each one.
$('.outer').on('mouseenter', function(e){
$(this).addClass('hover');
}).on('mouseleave', function(e){
$(this).removeClass('hover');
});
$('.inner').on('mouseenter', function(e){
$(this).addClass('hover');
$('.outer').removeClass('hover');
}).on('mouseleave', function(e){
$(this).removeClass('hover');
$('.outer').addClass('hover');
});
Demo

You can remove the class hover on the parent div when the mouse enters the inner div
Like this:
$('.outer, .inner').on('mouseenter', function(e){
$(this).addClass('hover');
$(this).parent(".outer").removeClass('hover');
}).on('mouseleave', function(e){
$(this).removeClass('hover');
$(this).parent(".outer").addClass('hover');
});
I feel like this is a bit of a hack and can be improved by being more specific with the selectors instead of creating just one function for both .outer and .inner
Example on: http://codepen.io/anon/pen/KzILE/

Related

Mouseover and click event conflict

I'm trying to use the on() event to bind both a click and mouseover event to a link, essentially to have hover behaviour on desktop and click for mobile and tablet. The issue I currently have is that both events are triggered at the same time. Is it possible to do this cleanly or should I just add a conditional for the screen width and apply the hover specifically on desktop, click event for mobile? Basic JS fiddle here: http://jsfiddle.net/4wr3da8p/
$('div').on('click mouseover', 'a', function(e) {
e.preventDefault();
$(this).toggleClass('active');
});
EDIT:
Updated the jsfiddle to better show what I'm trying to do. I want to toggle the display of an adjacent element, so I don't think CSS pseudo classes will help.
http://jsfiddle.net/4wr3da8p/
$('div').on('click mouseover', 'a', function(e) {
e.preventDefault();
$('.content').toggleClass('active');
});
You can use tap event with jquery for mobile and mouse over for desktop
I suspect what you are experiencing is that when you first move the mouse into position for a click (but before the actual click), the "active" class toggles on, but then when you click, that class toggles back to off. Such are the issues with a toggle operation.
If all you are trying to do is apply a certain class when the element becomes active or hovered and remove that class when it's not, you don't need JavaScript at all. You can do that with just CSS and the :hover and :active pseudo-classes. You won't need to worry about both scenarios being true at the same time and cancelling each other out.
div:active, div:hover { background:yellow; }
<div>
<p>This will become yellow when you hover over it or when you click it.</p>
<p>The class will no longer be applied when you move the mouse out of the area or after the click is done.</p>
</div>
You can utilize <input type="checkbox"> and <label> elements, change events attached to #bar and #foo elements, css :hover, :checked pseudo classes, general siblings selector ~.
$(function() {
$("#bar").change(function() {
if (this.checked) {
$(this).hide().add("#foo").prop("checked", false);
}
});
$("#foo").change(function() {
if (this.checked) {
$("[for=bar]").css("display", "inline-block !important");
}
});
});
#foo,
#bar,
span.bar,
[for="bar"] {
display: none;
}
[for="foo"]:hover ~ [for="bar"],
#foo:checked ~ [for="bar"],
[for="foo"]:hover ~ .bar,
#foo:checked ~ .bar {
display: inline-block;
}
[for="bar"] {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input type="checkbox" id="foo">
<label for="foo">foo</label>
<br/>
<br/>
<span class="bar">bar</span>
<input type="checkbox" id="bar">
<label id="close" for="bar">x</label>
jsfiddle http://jsfiddle.net/4wr3da8p/2/

Highlight an element on hover

I want to highlight an element on hover, and only that element.
This should mimic the behaviour of hovering over an element with chrome dev tools when you have the magnifying glass selected.
It's for a chrome extension I'm making.
I think I need a JS solution, as the pseudo :hover in css seems to apply to all elements in the background, i.e. container elements, so I'd need to prevent event bubbling in css, which as far as I can tell you can't do.
I have tried
$('body').children().mouseover(function(e){
$(".hova").removeClass("hova");
$(this).addClass("hova");
}).mouseout(function(e) {
$(this).removeClass("hova");
});
-css-
.hova {
background-color: pink;
}
and jquery's hover(), both always selects the container too.
I have also tried with css opacity, incase the background was covered, but it seems it always selects the parent element. I want the furthest child down the DOM that I am hovering over.
I'm sure there's some simple solution out there, maybe its over complicating as its in a chrome extension... I'm not sure
Is this what you need? http://jsbin.com/vidojamece/1/
Instead of adding the class to $(this) inside the handler, add the class to e.target (span) and return false so it doesn't bubble up to the div:
$('body').children().mouseover(function(e){
$(".hova").removeClass("hova");
$(e.target).addClass("hova");
return false;
}).mouseout(function(e) {
$(this).removeClass("hova");
});
You need to use the target element instead of 'this', which is the actual element that you hover over and use stopPropagation in order to not repeat the process for each element behind:
$('body').children().mouseover(function(e){
e.stopPropagation();
$(".hova").removeClass("hova");
$(e.target).addClass("hova");
}).mouseout(function(e) {
$(e.target).removeClass("hova");
});
You can do this with css (and js too):
*:hover {
background-color: pink;
}
or even
div:hover {
background-color: pink;
}
In js:
$('body').children().each(function() {
$(this).hover(function() {
$(".hova").removeClass("hova");
$(this).addClass("hova");
}, function() {
$(this).removeClass("hova");
});
});

mouse enter event is not working properly

Hi I am trying to hide a div on mouse enter on body, it is not working properly, the div I am trying to hide, will hide and comes again. Checkout this fiddle
Here is my code:
JS:
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseout(function(){
$('.jadu').show(10);
});
HTML:
<div class="jadu"></div>
CSS:
*{padding:0px;margin:0px;}
.jadu{
position:fixed;
width:100%;
height:100%;
background-color:#555;
opacity:0.8;
display:block;
z-index:3;
}
body{
background:red;
}
this is fiddle link: Fiddle
Simply use the mouseleave event.
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseleave(function(){
$('.jadu').show(10);
});
JS Fiddle
When you use mouseout on an element and there is a child in it (document > .jadu) the mouseout event is triggered when you hover the .jadu element (child).
Using mouseleave, this event won't be triggered when you hover a child of document.
See the fiddle;
http://jsfiddle.net/xibalbian/UaJZr/
$(document).mouseenter(function() {
$('.jadu').hide(10);
}).mouseleave(function(){
$('.jadu').show(10);
});
If the matched elements have no child element, both mouseout() and mouseleave() events are work exactly same.
If the matched elements have child element, both mouseout() and mouseleave() events are work different in the way of “event bubbling”.
You can see this page which explains clearly -> Difference between mouseout() and mouseleave()
Use mouseleave event. jsfiddle
$(document).mouseenter(function() {
$('.jadu').hide(10);
});
$(document).mouseleave(function(){
$('.jadu').show(10);
});
Visit: JsFiddle
/* Do not use equal time in hide and show: */
$(document).mouseenter(function() {
$('.jadu').hide(100);
}).mouseout(function(){
$('.jadu').show();
});

Can i handle other elements when hover?

html,
<div id="first">
<a>Come here</a>
</div>
<div id=second">
second div
</div>
css,
#first a:hover{
color:green;
/*i want to do this when hover */
#second{
background:green;
}
}
in here, if the user cursor goes to "come here", i want to change the other element #second's background color.
Is this possible using only css? or do i have to use jquery or javascript event?
#first:hover + #second{
background: green;
}
http://jsfiddle.net/DerekL/8rJmC/
Use ~ if #second is not directly after #first.
Notice that it is impossible to attach the :hover event to a directly using only CSS. The code above attaches it onto #first.
You can do it this way with jQuery if you really have to attach it to a:
$("#first > a").hover(function(){
$("#second").css(...);
}, ....);

Javascript - Div Box as a HyperLink + Nested Text HyperLink - Possible?

Seeing as though Nested Anchor Tags are not possible, could Javascript be utilized to have a Div Box hyperlink to Page-A, while having a word of a Text within the Div Box hyperlink to Page-B?
Have tried working with the following Javascript (works for hyperlinking the Box or the Text, but not both):
<script type="text/javascript">
// Content-Link Click Events
$('.content-link-page-a').click(function(){
window.location.href = "page-a.html";
});
$('.content-link-page-b').click(function(){
window.location.href = "page-b.html";
});
</script>
Here's some CSS:
<style>
.box {
height: 50px;
width: 100px;
border: 1px solid #000;
}
</style>
And here's the HTML:
<div class="box content-link-page-a">
<div id="username" class="content-link-page-b">UserName</div>
</div><!--/box-->
You should remove the A from around the inner DIV, give it a bigger z-index than the outer, and handle the inner click event with calling event.stopPropagation to prevent bubbling of the event to the outer div. Here is a fiddle to solve the task.
Sample for the inner handler:
$('.content-link-page-b').click(function(e){
alert("page-b.html");
e.stopPropagation();
});
EDIT: In my comment above, I mentioned e.preventDefault() call. I didn't mean that, because that means the native DOM element's handler will be prevented, and not the jQuery event bubbling.

Categories