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/
Related
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");
});
});
I need such a scenario at where if anyone hover on a div, another div will be hovered. Just like:
HTML
<div class="box"></div>
<div class="link-box">
Touch the Grey Box and I get hovered!
</div>
CSS:
.link-box a:hover {
color: red;
}
Foddle Work
If anyone hover on the div.box, div.link-box will get hovered I mean get the red color. Is it possible? Please, don't tell it like this CSS way:
.box:hover .link-box a {
color: red;
}
My scenario is not like this. I've more complex scenario. So, it's only possible with jQuery. As I ain't good at jQuery, I can't write the script. That's why I need your help. What's the jQuery for it? May be, something like this?
$('.box').hover(function(){
$('.link-box').hover();
});
..............................................Update..................................
All the answer is related with CSS. Basically, div.link-box is such a complex div at my webpage that if anyone hover on the div.link-box many action happened, like pop-up box coming, multiple child elements of div.link-boxwill change. All happened with jQuery + CSS. And I need all the hover action of div.link-box when anyone hover on div.box. I just make here div.link-box as a link to make you understand my problem. But, basically it's not just css change. So, is it possible to bring all div.link-box hover action by hover on another div/button/link just like div.box by jQuery ?
As long as they stay in the same layout you can use the adjacent selector (+) in css.
Updated Fiddle
.link-box a:hover, .box:hover + .link-box a{
color: red;
}
The important thing to remember about the adject selector is that the two divs have to have the same parent, and the box has to immediately precede the second div.
More information on the adjacent selector
Edit:
Another option would be to wrap both divs in another div, and use the hover of the wrapper div.
This second option doesn't have the drawbacks of using the adjacent selector. As long as the anchor is anywhere inside of the wrapper, it will be styled when any part of the wrapper is hovered.
FIDDLE
Like so:
<div class='box-wrapper'>
<div class="box"></div>
<div class="link-box"> Touch the Grey Box and I get hovered!
</div>
</div>
with the following style:
.box-wrapper:hover a {
color: red;
}
Create a CSS class called "hover" (to affect you a make it .hover a)
.hover a
{
color: red;
}
Then your JQuery would read:
$('.box').hover(function(){
$(".link-box").toggleClass("hover");
});
Instead of the :hover css selector, I would use classes.
CSS:
.hover{
color:red;
}
JS:
$('.box').hover(
function(){
$('.link-box').addClass('.hover');
},
function(){
$('.link-box').removeClass('hover');
}
);
I have an interesting problem in disabling mouse events using the 'pointer-events' css styling.
Please refer the fiddle. It has a parent and two children div, and I make 'pointer-events' as 'none' to one of the children. If I click on that div, its mouse listeners are not triggered (this is expected) but mouse events of its parent div is triggered.
$('#parent').click(function(){
console.log("Parent clicked");
});
How to disable mouse events on the parent div, if I clicked on its children which are disabled for mouse events?
One option is to filter using an "if" condition on the parent click. But i don't need it, as I want to listen for mouse events on 'divs' present behind the parent.
Please provide some help :)
thanks,
Rethna
I couldnt make the pointer-events work as I intended, so I changed the javascript in order to achieve what you wanted.
What i did was to event.stopPropagation on the child2, so you can click him and only fire his click event, not his parent's click event.
By the way, i know little about jquery, so I wrote a mixed beetwen pure javascript and jquery, hope someone can help me translate that.
Here comes the fiddle
CSS:
#child1{
background-color:#ff0000;
width:100px;
height:100px;
pointer-events: all;
}
#child2{
background-color:#00ff00;
width:100px;
height:100px;
pointer-events: all;
}
#parent{
pointer-events: none;
}
Javascript:
$(document).ready(function(){
document.getElementById('child1').addEventListener('click', function(){
console.log("child1 clicked");
}, false);
document.getElementById('child2').addEventListener('click', function(e){
e.stopImmediatePropagation();
console.log("child2 clicked");
}, false);
document.getElementById('parent').addEventListener('click', function(){
console.log("Parent clicked");
}, false);
});
For anyone stumbling across this post, here's something very useful..
el.setPointerCapture() will focus all pointer events on given element.
not only do you isolate the node, but also gain a lot of performance as the browser stops performing hittests on anything else
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/
I have created a dropdown menu with css. Here is the HTML code:
<li class="menu" id="menu">
<div class="dropdown">
<div class="col1"> ...
here is the css:
.dropdown {
visibility:hidden;
/*...*/
}
#menu li:hover .dropdown{
visibility:visible;
}
This works perfectly. In jQuery I handle the click event for the links in this menu and I want to use jQuery to hide the dropdown whenever the user clicks on a link so it goes away.
I tried these both (note: I haven't used these together.):
$('.dropdown').css('visibility', 'hidden'); //didn't work
$('.dropdown').hide(); //didn't work either
they both hide the menu but the problem is when they hide it, I don't get the menu again whenever I hover the mouse over the item.
You have to define what happens when the mouse is hovering the button and what happens when it's not. Something like this:
jQuery(document).ready(function(){
jQuery(".dropdown").hover(function() {
/* hovering actions */
}, function() {
/* non-hovering functions */
});
});
That's because jQuery's hide() method uses the rule "display:none" over that elemenent, in this case ".dropdown", to hide it, therefore, by definition, the "visibility" can't work on an element that has the rule "display:none" assigned to it.
Use jQuery to make the dropdown effect instead of a bunch of CSS rules.
Okay, what is actually happening is when you you set $('.dropdown').css('visibility', 'hidden'); on the element, it adds this to the style attribute of the element, inline (you can check this with Firebug). So the CSS
#menu li:hover .dropdown{
visibility:visible;
}
doesn't have any effect because inline styles take precedence. .dropdown elements will always be set as hidden now.