My Script Snippet:
$(document).on('click', function(e) {
if ($(e.target).closest('.input-actions.Actions').length) {
var CurrentWidth = $(e.target).width() + 'px',
OpenWidth = '308px';
if ($(e.target).is('.dropdown-toggle')) {
$(e.target).animate({
width:OpenWidth
}, {
direction: 'right',
duration: 500,
});
setTimeout(function() {
$(e.target).parent().find('.dropdown-menu').slideDown({
height: '249px',
}, {
duration: 500,
});
}, 800);
}
}
});
Script Explanation:
On click of the link, the button changes with to match the drop down via animate then with the delay the drop down slides down.
What I'd Like To Achieve:
I'd like to add, in the most simplistic way, a toggle feature so that upon clicking again the reverse occurs animating the $(e.target) back to CurrentWidth and $(e.target).parent().find('.dropdown-menu') to slide back up and hide.
Related
I have a header that I want to be hidden once you start scrolling into the content of my webpage. This is the code I used:
$(window).scroll(function() {
if ($(this).scrollTop() > 900) {
$("header").css({
display: "none"
});
}
});
$(window).scroll(function() {
if ($(this).scrollTop() > 900) {
$("#msg").css({
display: "none"
});
}
});
The header does disappear correctly however, when I start scrolling some of my other elements disappear temporarily and the page jumps around. When I scroll to the top the header is gone (like I want) and the other elements are in place like they should be. My other elements are also triggered to appear when scrolling using ScrollReveal so I don't know if this may be interfering somehow.
ScrollReveal().reveal(".glitch", {
delay: 3000,
easing: "ease-in"
});
ScrollReveal().reveal("header", {
delay: 5000,
easing: "ease-in"
});
ScrollReveal().reveal(".arrow", {
delay: 7000,
distance: "-50px",
easing: "ease-in"
});
ScrollReveal().reveal("nav", {
delay: 8000,
easing: "ease-in"
});
There are a couple of things you can do to prevent that. Basically, the problem is related to the fact that you are re-hiding that div repeatedly, even after it is hidden - so many times, in fact, that you are "flooding" the browser.
1. Create a "state" variable
Create a variable that stores the current visibility state of the element, and only hide the div if the var says it hasn't yet been hidden:
var hdrVisible = true, msgVisible = true;
$(window).scroll(function() {
if ($(this).scrollTop() > 900) {
if (hdrVisible){
$("header").hide();
hdrVisible = false;
}
}
});
$(window).scroll(function() {
if ($(this).scrollTop() > 900) {
if (msgVisible){
$("#msg").hide();
msgVisible = false;
}
}
});
2. Use a Debouncer
Also, you should look into the debounce plugin. It will allow you to limit the number of times that a function will fire.
The window.scroll() function fires many times per second - to see how many times, view this example:
$(window).scroll(function(){
let tmp = $(window).scrollTop();
$('#msg').html(tmp);
});
body{height:5000px;}
#msg{position:fixed;top:0;right:0;padding:15px;background:wheat;text-align:center;font-size:1.3rem;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="msg"></div>
Im curious , is that possible to count toggle ? Because I have one problem , when I hover it and hover out multiple times and select one of the item, the button will push to bottom and not able to seen. Or that is another way to fixed this problem ?
updated
Not multiple times even I hover in and hover out and hover it again it also push to bottom.
click here for js fiddle
JS
$("#popup_survey_whitebox").hover(function () {
$('#popup_survey_whitebox_content').stop().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(orig); // Here put the original text.
}).css('position', 'relative');
}, function () {
$('#popup_survey_whitebox_content').stop().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(newText); // Here put the new text with "..."
}).css('position', 'relative');
});
Finally I found a way to fixed this problem .
$("#popup_survey_whitebox").hover(function () {
$('#popup_survey_whitebox_content').finish().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(orig); // Here put the original text.
}).css('position', 'relative');
}, function () {
$('#popup_survey_whitebox_content').finish().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(newText); // Here put the new text with "..."
}).css('position', 'relative');
});
change $('#popup_survey_whitebox_content').stop() to $('#popup_survey_whitebox_content').finish() for both animate
I've implemented the baraja jquery plugin for a section on a 'web app' that I need to create.
Rather than the plugin spreading the cards on the click of a button, I've opted to alter the script and spread out the cards on hover. On the face of it this works but if you hover over the cards and back off quickly before the animation is finished the cards will stay open. And then when you hover over the 'deck' they close. I've created a codepen below to show this:
http://codepen.io/moy/pen/OPyGgw
I've tried using .stop(); but it doesn't seem to have an impact on the result. Can anyone help me with this?
Additionally I'd like the deck to be open on page load, then close after a second or 2. I tried this with $( document ).ready() including the baraja.fan call but that didn't trigger it - any ideas?
this one really tickled me ;) tried several things, but - as already told - the plugin doesn't expect to get the close animation call faster, then the opening animation will run.
so finally i build you the following.
- opening the fan, right at document ready
- created a timeout for the mouseleave, to wait for the opening animation duration, before closing it - you will have a 400ms delay when mouseleave the element, but it will close, even when you've been to fast...
$(document).ready(function () {
if ($("#baraja-el").length) {
var $el = $('#baraja-el');
baraja = $el.baraja();
}
//initial open
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
$('.baraja-container').addClass('open');
// navigation
$('#baraja-prev').on('click', function (event) {
baraja.previous();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1000") {
$(this).addClass('visited');
}
});
});
$('#baraja-next').on('click', function (event) {
baraja.next();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1010") {
$(this).addClass('visited');
}
});
});
$('.baraja-container').hover(function (event) {
if(!$(this).hasClass('open'))
{
$(this).addClass('open');
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
}
}, function (event) {
curBarCon = $(this);
setTimeout(function(){
curBarCon.removeClass('open');
baraja.close();
}, 400);
});
$('.baraja-container li').click(function () {
$(this).addClass('visited');
});
});
since i fiddled in your codepen, you should have the working version here: http://codepen.io/moy/pen/OPyGgw
but... it's really no perfect solution. i'd suggest to get another plugin or rework baraja to get callback functions, which would test if the animation is currently running and dequeue them if needed.
rgrds,
E
I have a menu with sub items inside it. In order to make animation effect I want, I need to retrieve sub-menu width,height and height of its first-child. Now my animation works ,but sometimes my sub-menu just "pops up" (it doesn't animate its width ).
Here is The Fiddle of the problem.
http://www.vasinternetposao.com/wordpressdevelopment/wp-content/themes/override/images/submenu_problem.png
I am using this code:
var j = jQuery.noConflict();
j(document).ready(function () {
j('ul.nav').removeClass('nav').addClass('jnav'); //Add jquery Class to our menu
j('ul.jnav li').hover(function () {
if (j(this).children('ul:first').hasClass('jsub-menu')) { //Let's check if "jsub-menu" Class is here
return false; //If it is ("jsub-menu" here) don't SlideDown...
} else { //Else slide down if no class
j(this).find('ul.sub-menu:first').not(':animated').slideDown(500);
}
}, function () {
j(this).find('ul:first').slideUp(500, function () {
j(this).removeClass('jsub-menu').addClass('sub-menu');
j(this).css({
'height': '',
'width': ''
});
});
});
j('ul.jnav ul.sub-menu a').hover(function () {
j(this).addClass('active');
if (j('.active').next('ul.sub-menu').length) { //If submenu exist...
j('.active').next('ul.sub-menu').css({
'visibility': 'hidden',
'opacity': '0',
'display': 'block'
}); //Show it so we can read its:
var get_width = j('.active').next('ul.sub-menu').outerWidth(true); //WIDTH
var get_height_of_first_child = j('.active').next('ul.sub-menu').children('li:first').outerHeight(true); //HEIGHT of its First Child
var get_submenu_height = j('.active').next('ul.sub-menu').outerHeight(true); //HEIGHT of our menu
j('.active').next('ul').removeClass('sub-menu') //Remove class from menu, add another class apply HEIGHT of FIRST CHILD and hide it again...
.addClass('jsub-menu').css({
'visibility': '',
'opacity': '',
'height': get_height_of_first_child + 'px',
'width': '0'
});
j('.active').next('.jsub-menu').animate({
width: get_width
}, 1000, function () { //Animate WIDTH
j('.active').next('.jsub-menu').animate({
height: get_submenu_height
}, 1000); //callback animate HEIGHT
});
} //End if
}, function () {
j('.active').removeClass('active');
});
});
I think that this is happening because my Slide Up/Down animations are conflicting with my animate with/height functions but I am not sure. I have tried to solve it by adding stop(),stop(true,true),stop(true,false) in numerous combinations but failed. I am trying to solve this for days now so you stackers are my only hope. Please help!
Thank you!!
I was finally able to replicate the error.
I wrote this code for you, to replace the code you have for the animation.
var animating = false;
function animate($elm, options, callback) {
if (animating)
return;
animating = true;
$elm.animate(options, 1000, function() {
animating = false;
if (callback != undefined)
callback();
});
}
Call it like this, from inside your hover callback.
animate(j('.active').next('.jsub-menu'),
{
'width': get_width,
'height' : get_submenu_height
});
Basically, it checks if another animation is already running, in which case it doesn't start it. The Flag is set to false when the animation stopped, and let's other animations go on.
You can also pass a callback to do something after the animation is completed, but in your case you don't need it, because you can animate the height and width in the same time.
I tested it for like a minute and it looked pretty smooth.
Here is the updated feedle: http://jsfiddle.net/gabrielcatalin/TNxJ4/1/
P.S. You may also want to use the $ sign instead of 'j' for jQuery wrappers.
I currently have a carousel slider which contains some text. When the user clicks the 'next' button the .carousel-text div sides up hiding the text, the carousel moves to the next slide then the .carousel-text on the next slide slides down to reveal the text.
This works fine some of the time but sometimes it will go wrong and the text will slide up and down before the carousel moves on. I'm assuming this is because the next button is clicked before the whole sequence has finished (the whole thing takes 2 seconds). Is there a way to make sure the whole thing is complete before it is called again?
jQuery("#arrow-right").click(function () {
jQuery('.carousel-text').animate({
marginTop: "-260px"
}, 500, function() {
jQuery('.carousel-inner').animate({
marginLeft: "-700px"
}, 1000, function() {
jQuery('.carousel-text').animate({
marginTop: "0px"
}, 500, function() {
// Animation complete.
});
});
});
}
EDIT: Just made a jsfiddle here: http://jsfiddle.net/UGE44/
Place a ".stop(true, true)" before you animate. This will stop the previous animations and allow the new ones to start all at the same time. Would look something like this:
jQuery('.carousel-text').stop(true, true).animate({
marginTop: "-260px"
}, 500, function() {
jQuery('.carousel-inner').stop(true, true).animate({
marginLeft: "-700px"
}, 1000, function() {
jQuery('.carousel-text').stop(true, true).animate({
marginTop: "0px"
}, 500, function() {
// Animation complete.
});
});
});
Your may want to play around with which animates you place them before, as it may not need to be in all three spots.
Set "animating" flag before animate and clear it when animation is done.
jQuery("#arrow-right").click(function () {
var $text = jQuery('.carousel-text');
if ($text.data('animating') !== true) {
$text.data('animating', true)
.animate({
marginTop: "-260px"
}, 500, function() {
jQuery('.carousel-inner').animate({
marginLeft: "-700px"
}, 1000, function() {
jQuery('.carousel-text').animate({
marginTop: "0px"
}, 500, function() {
$text.data('animating', false);
// Animation complete.
});
});
});
}
}