Rebind Hover Effect After Click JQuery - javascript

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.

Related

Prevent particular child element from firing parent's mouseover event in jQuery

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();
});

Run a javascript only on the child of the element that triggered it

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/

Javascript - Reversing a Modal Animation

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 :)

mouseover animation weird behaviour

I'm creating a simple animation with jquery.
The animation consists on a div being slided left when the mouse hovers it.
This is my html:
<div class="item">
<div class="content" onmouseover="over(this)" onmouseout="out(this)">
<div class="image">
<img src="http://aranciamato.it/wp-content/uploads/2013/09/insetti-700x250.jpg" width="300"/>
</div>
<div class="text">
Some useful content
</div>
</div>
</div>
This is the js:
function over(element) {
$(element).stop().animate({left: "-250"}, 500);
}
function out(element) {
$(element).stop().animate({left: "0"}, 500);
}
This is the css:
.item {
position: relative;
width: 300px;
height: 107px;
overflow:hidden;
}
.item .content {
position: absolute;
top:0;
left:0;
width: 600px;
height: 107px;
}
.item .content .image {
position:absolute;
top: 0;
left: 0;
}
.item .content .text{
position:absolute;
top: 0;
left: 300px;
width: 250px
}
.item {
border: 1px solid black;
}
The animation works properly, but I noticed that if you move the cursor over the left border of the .image div while the animation is running, it pauses for a moment and then resumes.
I don't know how to explain this better, so here you can find a JSFiddle, and here you can find a video that demonstrates the behaviour
My question is: Why is the animation behaving like this? How can I make the animation continue without pausing?
Use mouseenter and mouseleave instead
<div class="content" onmouseenter="over(this)" onmouseleave="out(this)">
DEMO
Your jsfiddle is working for me. Also, its better for you to use the $(el).hover() function jQuery provides, for example:
$('.content').hover(function() {
// Mouseover
}, function() {
// Mouseout
});
Well, you can use your hover event on the parent element (in this case .item) and animate the child element (.content). If you're using jQuery, just use .hover () instead of those two mouse events.
When you move the cursor out of the image div then a mouseout event fires - you move out of the image - and the out function is called, making the animation stop. Right after that the mouseover event fires - you move over the text - and the over function is called.
You attached the event handlers to the content div, i.e. they are called whenever the event fires on itself, but also when the event fires on one of it's descendants.
The reason why it's working with mousenter and mouseleave is that those events are handled differently by the browser. But be aware that they are not supported by all browsers.

Map not opening without refreshing page once closed

The website i am currently working on has a pop out div with a map of locations on it, my problem is once the pop up div has been closed i then have to refresh the page to open the div again
It is running jquery - here is the code
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#view_map_of_stocklists_link').click(function() {
//$('#popupdiv').show('slow');
$("#popupdiv").css('visibility', 'visible');
$("#mappy").css('opacity', '1');
});
$('.closepopup').click(function() {
$('#popupdiv').hide('slow');
});
});
</script>
The styling
<style>
#popupdiv
{
position: absolute;
left: 50%;
top: 50%;
background-color: white;
z-index: 100;
height: 600px;
margin-top: -200px;
width: 960px;
margin-left: -500px;
padding: 20px;
}
#view_map_of_stocklists_link:hover {
cursor:pointer;
}
.closepopup {
margin-top: 60px;
border: 1px solid #ccc;
background-color: #000;
color: white;
cursor: pointer;
}
</style>
and then the HTML itself
<div id="popupdiv" style="visibility:hidden;">
<center>
<iframe style="opacity:0;" id="mappy" src="http://mapsengine.google.com/map/embed?mid=zNedxWZ7lai0.krRxVqZZmyns" width="900" height="500"></iframe>
<div class="closepopup" style="width:200px">Close</div>
</center>
</div>
<h2 class="bold skin-font-color1">Our Beloved Stockists</h2>
<h5 class="skin-font-color1 p-wrapper"><!-- client txt --> <div id="view_map_of_stocklists_link" class="skin-font-color4">
<h4>View map of stockists</h4>
</div>
The website is http://www.tee-ze.co.uk/sosmoothies/
Cheers
You are setting 'visibility' to 'visible' instead of 'display' to 'block'.
When jQuery .hide() is called it ultimately saves the previous display value and sets it to display:none; So you should be doing something like:
$('#view_map_of_stocklists_link').click(function() {
$('#popupdiv').hide('slow');
});
Which I just realized you have commented out in your code. I wish I could leave a comment but I need more rep.
Edit:
Sorry for complaining in may previous answer.
I just tried uncommenting the existing code and removing the visibilty stuff and that works just fine in your site. Try it.
The way you're showing the popup map doesn't match the way you're hiding it.
You show it with:
$("#popupdiv").css('visibility', 'visible');
But you hide it with:
$('#popupdiv').hide('slow');
That fades it out but ultimately sets the CSS style display: none on the #popupdiv element.
When you try to show it again, it still has display: none on it. Setting the visibility doesn't affect the display style.
You need to make the hide and show match up. Either use the visibility style, or the display style, but use the same one for both hiding and showing (and jQuery's .show() method uses display).
For example, you might create the <div> with display: none instead of visibility: hidden, and then you can use jQuery's .show() and .hide() consistently.

Categories