On hover add / remove class - not always working - javascript

I'm implementing some animation by adding and removing classes to an element on mouseover and mouseout. I'm using this method as I found using CSS alone was not reliable; the animation would not complete if the mouse exited the element before the animation finished.
So I have the following code:
<div class="one flip-container">
<div class="flipper">
<div class="front">
<!-- front content -->
</div>
<div class="back">
<!-- back content -->
</div>
</div>
</div>
<script>
jQuery(".flip-container").hover(function () {
jQuery(this).addClass("hover");
},function () {
jQuery(this).delay(2000).queue(function(){
jQuery(this).removeClass("hover");
});
});
</script>
<style>
.flip-container.hover .flipper {
transform: rotateY(180deg);
}
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
</style>
This works but sometimes the class 'hover' is not removed, it stays, leaving the element in its animated state. Any idea how to make this more reliable?

Try using mouseenter and then set a timeout function to remove the class that way you wont be adding and removing classes except once each time the mouse enters the area. Also you may want to check to see if the area already has the class to avoid the function from being executed too many times like so:
jQuery(".flip-container").mouseenter(function () {
var el = jQuery(this);
if(!el.hasClass("hover")){
el.addClass("hover");
setTimeout(function(){
el.removeClass("hover");
}, 2000);
}
});
Here is a working fiddle Fiddle Demo

Related

How to change the background image "on click" with jQuery?

I'm trying to make animation effect for background, it should listen an event that will change images on click.
For instance, I click Sajo Hapyo it should change the background image.
Main issue is that all images will be having different background-images and I'm really stuck with this.
I used backgroundColor: green in my JS for test, since wanted to check, whether it works or not.
At the final version, the background images will be added and it should change on click with nice jquery UI (effect).
Here is screenshot
Please help me out
Here is my code
HTML
<section id="main-showcase">
<div class="showcase-wrapper">
<div class="left-main col-lg-3 col-md-3">
<div class="shadow-effect"><p class="ottogi">OTTOGI</p></div>
<div class="shadow-effect"><p class="sajo">Sajo Hapyo</p></div>
<div class="shadow-effect"><p class="natura">Natura Bogata</p></div>
<div class="shadow-effect"><p class="maloo">ТОО Малу</p></div>
<div class="shadow-effect"><p class="dongush">Dongsuh</p></div>
<div class="shadow-effect"><p class="may">ООО Май</p></div>
</div>
<div class="right-main col-lg-9 col-md-9">
<div class="inner-container">
<h1>Ottogi</h1>
<h2>Южно - Корейские продукты питания высочайшего качества!</h2>
</div>
<div class="box-container">
<div class="main-wrap">
<div id="main-slider" class="first-slider">
[[getImageList?
&tvname=`goods`
&tpl=`goodsSlider.tpl`
]]
</div>
</div>
</div>
</div>
</div>
</section>
JS
$('button.sajo').click(function () {
$('.right-main').animate({
backgroundColor: 'green',
}, 1500);
});
Actually instead of using the jQuery.animate(). You can simply toggle a class on the same element. It is a good practice to avoid animate() and using css3 animations instead.
codepen
Check the codepen sample here. It will explain how to use it. Instead of using keyframes and all. You can simply obtain it using trnasition.
span {
background-color: red;
padding: 10px;
transition: all 1.5s ease;
color: white;
}
.change-color {
background-color: blue;
}
First of all, I cannot see in the HTML the button where you apply the click event listener. However, I assume this button is located somewhere in your HTML code and what you want to do is change the background image on the main slider by clicking on it. To do so you simply have to do the following:
$('button.sajo').click(function () {
$('.right-main').animate({opacity: 0}, 'slow', function() {
$(this)
.css({'background-image': 'url(your_url)'}) //Change url to your image url
.animate({opacity: 1});
}
});
Note that since you do not specify the exact animation you want, I just provided an example with a fade in animation where opacity goes from 0 to 1. You can change this animation to a different one by changing the content of .animate() and leaving the .css() like i wrote there. Hope this helps!
You can use like that
var imageUrl = your image url
$('button.sajo').click(function () {
$('.right-main').css('background-image', 'url(' + imageUrl + ')');
});
.bgcolor{
animation: colorchange 50s; /* animation-name followed by duration in seconds */
/* you could also use milliseconds (ms) or something like 2.5s */
-webkit-animation: colorchange 50s; /* Chrome and Safari */
}
#keyframes colorchange
{
100% {background: green;}
}
#-webkit-keyframes colorchange /* Safari and Chrome - necessary duplicate */
{
100% {background: green;}
}`
Then add this class to the element you want to change the background of:
$('button.sajo').click(function () {
$('.right-main').addClass('bgcolor');
});

jQuery slideDown not functioning correctly

I wish to animate a div to make it appear and slide down with jQuery.
I have got my script to work where you hover over an image and another div slides in, should the user leave the mouse hover, the div will slide up and disappear.
Problem:
The first time i hover over the image, nothing happens. I have to leave my mouse and hover over it a second time for the effect to start working, I dont get why this is???
jQuery:
function show_action(){
$(function(){
$(".action").hide();
$(".logo").hover(
function(){ $(".action").slideDown(); },
function(){ $(".action").slideUp(); }
);
});
}
CSS:
#action_text{
display:none;
}
HTML:
<div class="center_container">
<div class="action" id="action_text"><span>Click To Upload</span></div>
<img src="images/logo.png" class="logo" onmouseover="show_action();">
</div>
No need to call .hide() on the .action element. Just give it display: none in your css, so that it will not show when the page loads. That way, you don't need the .stop() to clear the animation queue, and it also prevents a 'flicker' effect where your .action element will show up when the page loads for a brief moment until .hide() gets called.
$(document).ready(function() {
$('.logo').hover(
function() {
$(".action").slideDown();
},
function() {
$(".action").slideUp();
}
);
});
.action {
width: 100%;
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="logo">LOGO</span>
</div>
<div class="action">
<span>Action</span>
</div>
I think you are calling function show_action as onhover="show_action() remove that and move the rest code outside function wrapping, otherwise the hover() event handler will only bind after the first hover. additionally use stop() to clear the animation queue
$(function() {
$(".action").hide();
$(".logo").hover(
function() {
$(".action").stop().slideDown();
},
function() {
$(".action").stop().slideUp();
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class=logo>Hover here</div>
<div class=action>content<br>here</div>
Update : You can remove $(".action").hide(); by adding following css
.action {
display: none;
}

How to start animations when element appears on screen?

How is an HTML element animated as soon as it appears on screen?
I found an example on the stack overflow tour page, where info elements slide into the page as soon as you scroll down far enough. What is the trick behind that?
You need to use JavaScript to detect the location of the viewport and activate it when it becomes visible.
You can use JavaScript to detect and execute the transition and then CSS or JavaScript to do the animations.
There are many jquery based scripts available to accomplish this. Here is one example:
DEMO
1. Create a Html element you want to check if it's in the viewport.
<div class="demo"></div>
2. Load the jQuery javascript library and jQuery Viewport Checker plugin at the end of your document.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="viewportchecker.js"></script>
3. Call the plugin on this element and do something in the javascript.
<script>
$(document).ready(function(){
$('.demo').viewportChecker({
// Class to add to the elements when they are visible
classToAdd: 'visible',
// The offset of the elements (let them appear earlier or later)
offset: 100,
// Add the possibility to remove the class if the elements are not visible
repeat: false,
// Callback to do after a class was added to an element. Action will return "add" or "remove", depending if the class was added or removed
callbackFunction: function(elem, action){}
});
});
</script>
DOWNLOAD THIS SCRIPT
You can use the intersection Observer for this. The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
const startAnimation = (entries, observer) => {
entries.forEach(entry => {
entry.target.classList.toggle("slide-in-from-right", entry.isIntersecting);
});
};
const observer = new IntersectionObserver(startAnimation);
const options = { root: null, rootMargin: '0px', threshold: 1 };
const elements = document.querySelectorAll('.card');
elements.forEach(el => {
observer.observe(el, options);
});
.card {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.slide-in-from-right {
animation: 1.5s ease-out 0s 1 slideInFromRight forwards;
}
#keyframes slideInFromRight {
0% {
transform: translateX(50%);
}
100% {
transform: translateX(0);
}
}
<div class="card">
<h2>Card one</h2>
</div>
<div class="card">
<h2>Card two</h2>
</div>
<div class="card">
<h2>Card three</h2>
</div>

stopPropagation() div inside div onmouseover

I want to put a div inside another div, and when the user put the mouse on the parent div the two divs show up.
The problem is that when I put the mouse over the parent div the two divs show up but when I move the mouse over the child div the show() function execute it self again, how can I stop that?
HTML code:
<div id="parent" onmouseover="show(this)">
<div id="child"></div>
</div>
JavaScript code:
function show(element) {
setTimeout(function () {
opacity(element)
}, 100);
}
function opacity(element) {
element.style.opacity = "1"
}
This can and should be solved using CSS only, without JavaScript.
Example
<div id="parent">
Parent Text
<div id="child">Child Text</div>
</div>
#parent {
opacity: .2;
transition: .1s opacity;
}
#parent:hover {
opacity: 1;
}
using jquery :
$('#child').hover(function(e){e.stopPropagation();});
with normal js :
a simple google search for javascript stopPropagation()
Javascript : How to enable stopPropagation?

jQuery hover animation efficiency

I've got my hover working - but i'm interested in trying to make it more efficient as it does seems to 'lag' when it's finding the .overlay div. I also had the issue where I was animating all .overlay divs on a page, which I consider to be quite a noob mistake.
Anyway, let's learn how to make the below better!
jQuery:
// get aside feature
var aside_feature = $('aside .feature');
// on hover, fade it in
$( aside_feature ).hover(function() {
// get the overlay div
var feature_overlay = $(this).find('.overlay');
$(feature_overlay).stop().fadeIn();
// on hover out, fade it out
}, function() {
$(this).find('.overlay').stop().fadeOut();
});
Markup:
<aside>
<div class="feature">
<div class="overlay">
button
</div><!-- overlay -->
<div class="text">
<p>text</p>
</div><!-- .text-->
<div class="image">
<figure>
<img src="" alt="">
</figure>
</div><!-- .image -->
</div><!-- .feature -->
</aside><!-- aside -->
Fiddle: http://jsfiddle.net/9xRML/5/
Edit - Final Code
Thanks #Shomz, and #Afro.
Final code choices were to use tranisitons, and coupled with modernizr detection for transitions, I changed my hidden overlay div to opacity: 0; *display:none; and javascript as a fallback:
CSS
.overlay {
*display: none;
opacity: 0;
transition: 0.4s all linear;
}
.overlay:hover {
opacity: 1;
}
jQuery
$(function () {
/*=====================================
= Feature overlay =
=====================================*/
if (!Modernizr.csstransitions) {
// get aside feature
var aside_feature = $('aside .feature');
// on hover, fade it in
$( aside_feature ).hover(function() {
$(this).find('.overlay').stop(true, true).fadeIn();
// on hover out, fade it out
}, function() {
$(this).find('.overlay').stop(true, true).fadeOut();
});
}
});
With risking of having my answer out of scope here, if you want to really get performance, you should switch to CSS animations. It's totally possible with your example by setting the default opacity of the overlay to 0 (instead of display: none;) and making it show up on .feature:hover. The trick is to add the transition property like this:
// applies a 4ms transition to any possible property with no easing
transition: all .4s linear;
See the whole example here: http://jsfiddle.net/9xRML/6/
See a nice article about the performance difference (CSS vs. JS) here: http://css3.bradshawenterprises.com/blog/jquery-vs-css3-transitions/ (there are many more, of course)
I think I have solved your issue using the same HTML but changing the following:
JQuery
$('aside .feature').hover(function() {
$(this).find('.overlay').stop(true, true).fadeIn();
}, function() {
$(this).find('.overlay').stop(true, true).fadeOut();
});
CSS
.feature {
background: #ccc;
}
.overlay {
display: none;
}
This means the overlay will only display on hover.
Details on .stop() can be found here.
.stop(true, true)
We can create a nice fade effect without the common problem of multiple queued animations by adding .stop(true, true) to the chain.
DEMO

Categories