I want to use jQuery to achieve multiple effects. When an user click on an element, this calls a set of functions inside that click handler. Is there a way in jQuery to have a delay between each action executing in the function?
Example would be:
$(function() {
$('.activator').on('click', function() {
$(this).toggleClass('animated');
$('.app').css('background',$(this).css('background'));
});
})
Instead of having the activator element perform the animation it receives from the class, and then the app receiving the background, they both happen at the same time and the animation can't even be seen. How can one set a delay between the two, or multiple?
Thanks!
If it's a CSS animation then you need to set an event for animationend / transitionend
$('.activator').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
$('.app').css('background',$(this).css('background'));
});
$('.activator').on('click', function() {
$(this).toggleClass('animated');
});
Demo
$('.activator').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function() {
$('.app').css('background', $(this).css('background'));
});
$('.activator').on('click', function() {
$(this).toggleClass('animated');
});
.activator {
transition: all 1s;
width: 200px;
height: 50px;
background: red;
}
.activator.animated {
height: 500px;
}
.app {
width: 32px;
height: 32px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="app"></div>
<div class="activator">Click me</div>
If it is a jQuery animation you would use one of the callback options, like complete, or pass a callback function as the last argument.
jQuery("div").animate({width:"500"},{
complete:function(){
$('.app').css('background', $(this).css('background'));
}
});
//Or
jQuery("div").animate({width:"500"},function(){
$('.app').css('background', $(this).css('background'));
});
There's JavaScript built-in function setTimeout() for delaying an action.
Have you tried using .delay() before the animation?
$(this).delay(500).toggleClass('animated');
Related
Is there any way to execute an already defined function on javascript everytime a modification occurs in the animation of the easing of the slideToggle() function?
Example:
SlideToggle("1000", "linear", functiontoexecute())
I would like functiontoexecute() to execute every step it occurs on the "linear" easing.
I have already looked on JQuery webpage for .slideToggle() and tried to use "progress" or "step" options... but either they don't perform as expected or I didn't use them properly...
For more details I am using JQuery 1.9.1
The jQuery documentation on how to use those parameters isn't the best, as none of the examples use it to its full capabilities. Here's an example using the progress function, but hopefully you can adapt this to whatever your needs are: -
$("#book")
.slideToggle({
duration: 400,
progress: functionToExecute,
complete: function () {
console.log('animation completed');
}
});
function functionToExecute(animation, progress, remainingMs) {
$('p').text('here and progress count is ' + progress);
}
.wrap {
height: 100px;
width: 200px;
margin: 10px 10px 10px 10px;
background-color: #2d8cd0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap" id="book">
<h2>1</h2>
</div>
<p>Progress: <span id="progress">0</span></p>
This is my first question here, feel free to tell me if I am not specific enough or whatever I do wrong!
I want a jquery method which change all divs with the class "passive" to height 500 px and passive-->active, so there would be another method which changes the height back to 100px. The first half is working, I got the class changed, but the second animation won't happen. All I have in html is one div with the class of passive.
$("document").ready(function(){
$(function() {
$(".passive").click(function(){
$(this).animate({height:'500px'});
$(this).addClass("active");
$(this).removeClass("passive");
});
$(".active").click(function(){
$(this).animate({height:'100px'});
$(this).addClass("passive");
$(this).removeClass("active");
});
});
});`
jQuery.animate() is costly and choppy. You will get a smoother transition by just toggling the class and using CSS to transition
.passive {
height:100px;
transition:height 1s;
}
.active {
height:300px;
}
Array
.from(document.querySelectorAll('.passive'))
.forEach(
e => e.addEventListener(
'click',
evnt => e.classList.toggle('active')
)
)
.container { display:flex; }
.container>div {
flex:1 auto;
}
.passive {
background-color:red;
margin:5px;
height:100px;
width:20px;
transition:height 1s;
}
.active {
height:300px;
}
<div class="container">
<div class="passive" tabindex=1></div>
<div class="passive" tabindex=2></div>
<div class="passive" tabindex=3></div>
</div>
You are trying to interact with a class added after the DOM loaded. By default, click functions will only work with elements that exist on load. You can either use event delegation or add a base class to the element. If you add a base class, you can simplify the click function.
You can do an if/else to check if the element has a certain class using hasClass. Also, you can chain together the $(this) methods inside the if/else blocks.
$("document").ready(function() {
$(function() {
$("baseclassname").click(function() {
if ($(this).hasClass('passive')) {
$(this).animate({ height: '500px' });
$(this).addClass("active");
$(this).removeClass("passive");
// $(this).animate({ height: '500px' }).addClass('active').removeClass('passive');
} else {
$(this).animate({ height: '100px' });
$(this).addClass("passive");
$(this).removeClass("active");
// $(this).animate({ height: '100px' }).addClass('passive').removeClass('active');
}
});
});
});
I want to hover all div under .wrapper div in order with a delay when the page is loaded. How can I do this with using jquery?
HTML
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</div>
Jquery
$('.wrapper').children().each(function(){
$(this).trigger('hover');
});
https://jsfiddle.net/drxvr1hn/
.trigger('hover') has been deprecated as it caused a great deal of maximum stack exceeded errors.
Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a shorthand for the string "mouseenter mouseleave". It attaches a single event handler for those two events, and the handler must examine event.type to determine whether the event is mouseenter or mouseleave. Do not confuse the "hover" pseudo-event-name with the .hover() method, which accepts one or two functions.
Trying to trigger the hover state via jQuery is a very browser/cpu intensive process and a lot of re-rendering of a page to ensure that your call is correct. Therefore the ability was removed but is possible with some JS but will almost certainly cause speed issues and/or stack issues which can cause browser crashes.
A good alternative would be to use classes like below:
$(document).ready(function() {
$('.wrapper div').on('mouseover', function() {
$('.wrapper div').addClass('hover');
}).on('mouseleave', function() {
$('.wrapper div').removeClass('hover');
});
});
.wrapper > div {
width: 100%;
height: 20px;
margin-bottom: 20px;
}
.first {
background-color: #468966;
}
.second {
background-color: #FFF0A5;
}
.third {
background-color: #FFB03B;
}
.first.hover {
background-color: #B64926;
}
.second.hover {
background-color: #8E2800;
}
.third.hover {
background-color: #464A66;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</div>
you need to set the timeOut interval
$(window).scroll(function() {
$('. wrapper'). children().each(function(index){
var _this = this;
setTimeout( function(){ $(_this).trigger('hover'); }, 200*index);
});
});
I'm totally new in js and jq. I'am trying force my #cont div to change height on hover with animation and back to previous height without hover, but I dont know how to achieve that. In my test it should make an alert (or make other function), right?
http://jsfiddle.net/JJh9z/1773/
<div id='cont'>
<ul>
<li>an item</li>
<li>an item</li>
<li>an item</li>
<li>an item</li>
<li>an item</li>
</ul>
<div id='ruch'>HOVER</div>
</div>
#cont {
border: 1px solid #000;
height: 200px;
overflow:hidden;
position:relative;
}
#ruch {
position:absolute;
bottom:0px;
}
var result = $("#cont").height();
$('#ruch').hover(function(){
$('#cont').animate({height:'300px'}, 500);
});
if (result == 300) {
alert(result)
}
Your if statement only runs once when the script is first loaded, so no it won't alert each time someone hovers. it is not an event listener.
You need to add another event listener for when the mouse leaves the element (mouseout). See this modified code:
$('#ruch').hover(function(){
$('#cont').animate({height:'300px'}, 500);
});
$('#ruch').mouseout(function(){
$('#cont').animate({height:'200px'}, 500);
});
http://jsfiddle.net/JJh9z/1775/
http://api.jquery.com/hover/
You can specify a handleout event handler, in which you'd restore the element to its previous height.
You also should select not the 'HOVER' div (it's small) but a bigger element (like cont):
$('#cont').hover(
function () {
$('#cont').animate({
height: '300px'
}, 500);
},
function () {
$('#cont').animate({
height: '200px'
}, 500);
});
Here, I've specified a hover-out handler, and focused on 'cont' instead of 'ruch'
http://jsfiddle.net/JJh9z/1773/
There are several ways of doing this. One is to call the 'after animation completes function'. which takes another function as option.. the below example alerts 'Hii' after animating the height to 300px.
$( "#ruch").hover(function() {
$( "#cont" ).animate({
height: "300px"
}, {
duration: 500,
complete: function() {
alert('Hii');
}
});
});
To prevent multiple animations for one hover event since #ruch moves from under the mouse pointer during hover animation, use the following and a current version of jQuery:
var result = $("#cont").height();
$('#ruch').on( 'mouseenter', function(){
$('#cont').animate({height:'300px'}, 500, function() {
alert( result );
});
});
$('#cont').on( 'mouseleave', function(){
if( $(this).height() != result ) {
$(this).animate({height:result}, 500);
}
});
Once the #cont expands the mouse is no longer over #ruch and any slight movement would fire mouseleave and the #cont collapses. To prevent that, attach the mouseleave event to #cont as above.
You could play around with some webkit transitions as well, which is pretty easy.
The problem with adding an event listener for when the mouse leaves the even and queuing up an animation is that you can end up with a queue of many animations if you move your mouse crazily over the div, while this method will only do one animation.
#cont {
border: 1px solid #000;
height: 200px;
overflow:hidden;
position:relative;
-webkit-transition: 0.5s;
}
#ruch {
position:absolute;
bottom:0px;
}
$(document).on('mouseover', '#cont', function() {
document.getElementById('cont').style.height = 300;
});
$(document).on('mouseleave', '#cont', function() {
document.getElementById('cont').style.height = 200;
});
So i'm learning some jQuery at the moment and got somewhat stuck with this .click function. I'm trying to "turn a light on and off", so to speak.
I am able to do so, but only once. Why is that, that my code only runs for one click event per item, and how should i improve it?
Link to my JSfiddle.
HTML
<div class="lightOn"></div>
<div class="lightOff"></div>
jQuery
$('.lightOn').click(function() {
$(this).removeClass('lightOn');
$(this).addClass('lightOff');
});
$('.lightOff').click(function() {
$(this).removeClass('lightOff');
$(this).addClass('lightOn');
});
CSS
.lightOn {
height: 90px;
width:90px;
background-color:yellow;
border-radius: 100%;
float:left;
margin:10px;
}
.lightOff {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
The issue is because you are removing the class you are selecting by, so for successive clicks the element no longer exists. Instead have a common class which remains, but add one to it to light up the object. Try this:
<div class="light"></div>
<div class="light"></div>
.light.on {
background-color:yellow;
}
.light {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
$('.light').click(function() {
$(this).toggleClass('on');
});
Example fiddle
This method has the benefit of being able to handle x number of .light elements wihtout having to amend the jQuery selector you use.
The problem is that you bind the functions to elements, not to selectors. That is to say, you bind a function that removes the class lightOn to the element that had that class originally. That function only ever removes the lightOn class and adds the lightOff class, even if that has already been done once.
There are two ways to fix this. One is with on and event delegation, which allows you to do something akin to binding to a selector. It attaches the handler to a parent element, and makes use of the fact that all ancestor elements are notified of events that originated on their descendents. So the function might be bound to document.body, but only elements that originated on an element matching the .lightOn selector will trigger the handler:
$(document.body).on('click', '.lightOn', function() {
$(this).removeClass('lightOn').addClass('lightOff');
}).on('click', '.lightOff', function() {
$(this).removeClass('lightOff').addClass('lightOn');
});
http://jsfiddle.net/lonesomeday/C6f7u/5/
Better, however, is to make use of jQuery's toggleClass function, which removes classes if the element currently has them and adds them if it doesn't.
$('.lightOn,.lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
http://jsfiddle.net/lonesomeday/C6f7u/2/
What about
$('.lightOn, .lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
Demo: Fiddle
You can try using toogleClass of jquery
http://api.jquery.com/toggleClass/
It's a good practice to attach your events to the parent element. In your case this is even mandatory, because you are changing the classes, which are used during the event binding. So, your HTML:
<div class="ligths">
<div class="lightOn"></div>
<div class="lightOff"></div>
</div>
JS:
$(".ligths").on("click", "div", function(e) {
var el = $(this);
if(el.hasClass("lightOn")) {
el.removeClass("lightOn").addClass("lightOff");
} else {
el.removeClass("lightOff").addClass("lightOn");
}
});
JSFiddle: http://jsfiddle.net/C6f7u/7/