I have parent element which has mouseover event handler implemented using .mouseover() in Jquery.
It has 2 child elements, one contains image element, and second contains description element which has absolute position. On parent mouseover description slides on the image element.
Simplified version of code for the project would look like this:
$('.main-parent').mouseenter(function(){
$(this).addClass('item-hovered');
}).mouseleave(function(){
$(this).removeClass('item-hovered');
});
.main-parent {
position: relative;
}
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-parent">
<div class="child-image">
<img src="https://www.w3schools.com/w3css/img_lights.jpg">
</div>
<div class="child-description">
<h4 class="title">Title</h4>
<p class="subtitle">Subtitle</p>
<p>Lorem ipsum paragraph...</p>
</div>
</div>
As expected, .child-description is firing mouseover bind to .main-parent element, as it is its child and a part of it.
Is there a way to ignore .child-description element so that it doesn't fire function on mouseover event. The thing is before you hover the element, it is bellow the image made "invisible" to user using opacity: 0;, but it still can be hovered and used to fire mouseover of parent element.
I haven't find answer for this particular solution on stackoverflow, and if there is let me know. I appreciate your help :)
Yes, you would intercept the event for that child and then call event.preventDefault() and event.stopPropagation() as shown below.
Also, JQuery no longer recommends event shortcut methods, like mouseenter. Instead, they suggest using on().
$(".child-description").on("mouseover", function(event){
event.preventDefault(); // Cancel the event for this element
event.stopPropagation(); // Prevent the event from propagating to other elements
});
$('.main-parent').on("mouseenter", function(){
$(this).addClass('item-hovered');
}).on("mouseleave", function(){
$(this).removeClass('item-hovered');
});
.main-parent {
position: relative;
}
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-parent">
<div class="child-image">
<img src="https://www.w3schools.com/w3css/img_lights.jpg">
</div>
<div class="child-description">
<h4 class="title">Title</h4>
<p class="subtitle">Subtitle</p>
<p>Lorem ipsum paragraph...</p>
</div>
</div>
check whether child-description is the target of the event
$('.main-parent').mouseenter(function (e) {
if (!$(e.target).hasClass('child-description')) {
$(this).addClass('item-hovered');
}
}).mouseleave(function () {
$(this).removeClass('item-hovered');
});
Trying adding the following css rule to .child-description.
pointer-events: none;
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
pointer-events: none;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
pointer-events: auto;
}
This should prevent the element from responding to any mouse events. You will have to swap pointer-events: none; for pointer-events: auto; once you want the element to register interactions.
https://caniuse.com/#feat=pointer-events
I see some interesting answers here, so, I thought I would offer my own.
Why not use event.target and (in this particular case) event.target.className? Sample JSBIN Demo Online
For instance...
$('.main-parent').mouseover(function(e) {
if(e.target.className == 'subtitle') {
console.log("Child mouseover!");
return; // child mouseover, ignore
}
console.log("Parent mouseover!");
return true; // parent mouseover, activate some behavior
});
The advantage here should be observable -- you have quick, easy control of the paths of logic in relatively little code.
You should be able to prevent this using the stopPropagation method:
$('.child-description').on("mouseenter mouseleave", function(event) {
event.stopPropagation();
});
Related
I have a div element with a CSS pseudo-element ::before used as a close button (instead of using an actual button). How do I apply an event listener to only the pseudo-element?
HTML
<div id="box"></div>
CSS
#box:before
{
background-image: url(close.png);
content: '';
display: block;
height: 20px;
position: absolute;
top: -10px;
right: -10px;
width: 20px;
}
#box
{
height: 100px;
width: 100px;
}
Was looking for a solution and found this thread. Now want to share my workaround:
CSS
element { pointer-events: none; }
element::after { pointer-events: all; }
JS
element.addEventListener('click', function() { ... });
This works if you don't need any pointer events on element. Check it in action.
No. The pseudo-element does not exist in the DOM so it has no HTMLElementNode object representing it.
There is no :before and :after selector in jQuery. However as an alternative, you can check the location of the click event and check if it is on your pseudo-element:
(I haven't tested this)
style:
#mything {
width: 100px;
height: 100px;
position: relative;
background: blue;
}
#mything:after {
content: "x";
font-size: 10px;
position: absolute;
top: 0;
right: 0;
background: red;
width: 10px;
height: 10px;
}
javascript:
$('#mything').click(function(e) {
if (e.clientX > $(this).offset().left + 90 &&
e.clientY < $(this).offset().top + 10) {
// do something
}
});
html:
<div id="mything">Foo</div>
If the position and dimensions of the generated content are known, you can add a click handler on the element itself and check the relative mouse position before handling it.
This is perverse, but possible.
Generally speaking no as indicated by others. But in case your tag with pseudo-element is empty, such as glyphicon in bootstrap.
You can wrap a div or span or whatever tag suitable in your case. Glyphicons in bootstrap uses :before but on the page you can see that it has hover event caught.
Example:
<span>
<span class="glyphicon glyphicon-asterisk" aria-hidden="true"></span>
</span>
Suppose you want to add event to the above glyphicon, you can use jquery parent selector
$('glyphicon').parent('span').click(function() {
// awesome things
});
Just a small trick in case your tag is empty.
I'm making a personal website where pages are divided into 2. if you click on the left, the left part expands to the right and vice versa.
After the click action a button can supposedly reset the whole thing. It works great in this JSFiddle : http://jsfiddle.net/davidThomas/CFNUJ/1/
but I can't replicate it (http://guillaumeb.com/jsfiddle/split.html)
The "Show all" button does nothing...
Also I noticed that more recent versions of JQuery break the whole thing so I make use of v 1.x, like on the original example.
My JS skills are quite limited. Any help is appreciated
Here is the original code:
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
$('<button class="show">Show all</button>')
.appendTo('#wrapper');
});
$('.show').live('click',
function(){
$('#left-bg').animate(
{
'width': '50%'
},600);
$('#right-bg').animate(
{
'width': '50%'
},600);
$(this).remove();
});
#left-bg {
position: absolute;
top: 0;
left: 0;
bottom: 0;
background-color: #000;
color: #fff;
width: 50%;
margin: 0;
}
#right-bg {
position: absolute;
right: 0;
bottom: 0;
top: 0;
background-color: #fff;
color: 000;
width: 50%;
margin: 0;
}
.show {
position: absolute;
bottom: 0;
left: 50%;
margin-left: -2.5em;
width: 5em;
}
<div id="wrapper">
<div id="left-bg">
<p>Left stuff</p>
</div>
<div id="right-bg">
<p>Right stuff</p>
</div>
</div>
<div id="wrapper">
<div id="left-bg">
<p>Left stuff</p>
</div>
<div id="right-bg">
<p>Right stuff</p>
</div>
</div>
Add JQuery library reference in your page
Update the function as following:
$(function(){
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
$('<button class="show">Show all</button>')
.appendTo('#wrapper');
});
$(document).on('click','.show',
function(){
$('#left-bg').animate(
{
'width': '50%'
},600);
$('#right-bg').animate(
{
'width': '50%'
},600);
$(this).remove();
});
});
try this one may it works
$('.show').on('click',function(){
or
$(document).on('click','.show',function(){
because jQuery .live() has been removed in version 1.9 onwards.
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live(). To remove events bound with .on(), see .off(). To attach an event that runs only once and then removes itself, see .one()
thanks a lot for getting back to me, I do appreciate your help.
In the end I decided to do this in CSS with a click to trick the action via a very small JS.
I borrowed the code fomr here
https://codepen.io/thetallweeks/pen/boinE
<div class="box transform">
</div>
<input type="button" id="button" value="Click Me"></input>
================
.box {
background-color: #218D9B;
height: 100px;
width: 100px;
}
.transform {
-webkit-transition: all 2s ease;
-moz-transition: all 2s ease;
-o-transition: all 2s ease;
-ms-transition: all 2s ease;
transition: all 2s ease;
}
.transform-active {
background-color: #45CEE0;
height: 200px;
width: 200px;
}
================
$("#button").click(function() {
$('.transform').toggleClass('transform-active');
});
I want to run a javascript only upon the child from the element that triggered it. I have tried to make a research but couldn't find a way to get an answer. I know this might be simple but I am new to java.
Here is the fiddle of my problem FIDDLE.
What I want is that when I hover on the upper element, only its corresponding rating shows up, not both of them.
I have tried with find() without success
$('.product-image').hover(
function() {
$('.product-image').find('.ratings').css('opacity', '1');
},
function() {
$('.ratings').css('opacity', '0');
});
Thank you
Your problem is you do not select the element. You either need to change your code to use $(this) or $(evt.target) to get the element
How would I do it? With just CSS
.product-image + .ratings {
transition: opacity 0.5s ease;
opacity: 0;
}
.product-image:hover + .ratings {
opacity: 1;
}
.product-image {
height: 50px;
width: 50px;
background: red;
margin-bottom: 10px;
}
.ratings {
height: 50px;
width: 50px;
background: blue;
margin-bottom: 10px;
}
<div class="product">
<div class="product-image"></div>
<div class="ratings"></div>
</div>
<div class="product">
<div class="product-image"></div>
<div class="ratings"></div>
</div>
You can use event.target in your method body, which will give the element that triggered the hover event. Wrap it in $() to have jQuery context available.
$('.product-image').hover(function(event){
$(event.target).next('.ratings').css('opacity', '1');
}, function(event){
$(event.target).next('.ratings').css('opacity', '0');
});
Also updated your jsFiddle: http://jsfiddle.net/Z33kk/21/
So I have this element #box that needs to have a hover effect that displaces itself when hovered. The element will hover correctly using .hover in jQuery, then I need it to be clicked to display something, but after its clicked it should not have the hover effect anymore, so I used .unbind to remove it. Now when the user reclicks the element it will hide the info and then reapply the hover effect. So like a toggle effect. My question is what is the cleanest way to do this.
HTML:
<div class="box" id="box">
<h1 class="headline">ABOUT ME</h1>
</div>
CSS:
.box {
height: 320px;
width: 320px;
background-color: rgba(0, 0, 0, 0.6);
position: relative;
left: 10px;
top: 10px;
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
-o-transition: all 1s;
}
.headline {
margin: 0 auto;
color: white;
text-align: center;
display: block;
padding-top: 130px;
font-family: 'Montserrat', sans-serif;
}
.box_hover {
left: 0px;
top: 0px;
height: 300px;
width: 300px;
}
JQuery:
$(".box").hover(
function() {
$(this).toggleClass("box_hover");
}
);
$('#box').click(function() {
$(this).unbind('mouseenter mouseleave');
});
Here is the JSFiddle
EDIT 1:
To clarify I need it to add the class when its hovered on, then when its clicked maintain the "mouseenter" appearance, then when its re-clicked go back to being able to be hovered and moving based on the "mouseenter", "mouseleave".
Thanks!
Other then unbinding the event you can use a Boolean variable which the click event would toggle, that would control if toggleClass is called or not:
var bind = true;
$(".box").hover(
function() {
if(bind) $(this).toggleClass("box_hover");
}
);
$('#box').click(function() {
bind = !bind;
});
Fiddle Example
You could delegate the mouseenter/mouseleave events on the element when it has the .hover-effect class. Then you can toggle that class when clicking on the element.
In doing so, the mouseenter/mouseleave events will only be triggered when the element has the .hover-effect class, and since the class is toggled on click, you are essentially binding and unbinding the hover event on each click.
Updated Example
$(document).on('mouseenter mouseleave', '.box.hover-effect', function (event) {
$(this).toggleClass("box-hover", event.type === 'mouseenter');
});
$('.box').on('click', function() {
$(this).toggleClass('hover-effect');
});
If I understand the intent correctly, you simply need to toggle the class on click as well:
$('#box').click(function() {
$(this).unbind('mouseenter mouseleave');
$(this).toggleClass("box_hover");
});
Updated JSFiddle showcasing this.
Hope this helps!
EDIT
Depending on how the link will function, you could use a jQuery Mobile popup, and you wouldn't need to change the bindings at all.
You'll need to include the external scripts:
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
And slightly change your HTML:
<div class="box" id="box">
<h1 class="headline">ABOUT ME</h1>
</div>
<div data-role="popup" id="aboutme" class="ui-content">
<h3>Welcome!</h3>
<p>Popup content</p>
</div>
Along with your CSS:
.headline a {
text-decoration: none;
color: inherit !important;
}
Then, for the jQuery, you can simply use:
$('#box').click(function() {
$(this).toggleClass("box_hover");
});
I've created a new JSFiddle showcasing that here.
I have a few items on a site I'm building that onclick activate a modal like this.
Right now the animation is a one-way in that, when you close it or click off from the modal's focus, it just disappears. From what I've been reading, people seems to use the fadeIn/slideIn animation for one time effects, but is it possible, to reverse the animation so instead of just changing display to none, it slides back out?
#modal{bottom: 0; opacity: 1; transition: bottom 400ms, opacity 400ms; }
#modal.hidden{bottom: -300px; opacity: 0}
Then in button click event:
$("#modal").addClass("hidden")
On close event:
$("#modal").removeClass("hidden")
If you need pure javascript, it would be a bit more code but essentially that's it
Depending on how you've structured your code, you can approach this in a few ways:
Make use of the animation-direction: reverse; CSS property
Use a Javascript framework (like jQuery) that enables manipulation of DOM elements (with jQuery you could do something like: $('element').slideIn(); to show the modal and $('element').slideOut(); to hide the modal).
Use CSS classes and apply / unapply them with Javascript (the option I'd recommend, and have given an example below):
$(document).ready(function() {
$('.open').on('click', function(e) {
e.preventDefault();
if ($('.modal').hasClass('hide')) {
$('.modal').removeClass('hide');
}
$('.modal').addClass('show');
});
$('.close').on('click', function(e) {
e.preventDefault();
$('.modal').addClass('hide');
if ($('.modal').hasClass('show')) {
$('.modal').removeClass('show');
}
});
});
.modal {
position: fixed;
top: 0;
left: 0;
width: 300px;
height: 300px;
left: -305px;
z-index: 999;
transition: all 0.3s ease;
background: #ffffff;
border: 1px solid blue;
}
.modal.show {
left: 150px;
}
.modal.hide {
left: -305px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click here to open modal</p>
<div class="modal">
<p>This is a modal window.</p>
<p>Click here to close</p>
</div>
Please note that this example is only there to illustrate a proof of concept - you'll need to tidy it yourself :)