Prevent animation during animation - javascript

I'm trying to do an animation, everything works fine but I can't seem to prevent user from clicking during the animation and breaking the page layout.
I have managed to stop user when the divs are moving but I can't prevent when one div is expanded.
This is my fiddle: http://fiddle.jshell.net/p2fo4ek0/18/
<div class="internet_wrap">
<div class="internet tel" id="off_wrap">
<div class="package" id="one">
<div class="inner_package">
<div class="title">title</div>
</div>
</div>
<div class="package" id="two">
<div class="inner_package">
<div class="title">title</div>
</div>
</div>
<div class="package" id="three">
<div class="inner_package">
<div class="title">title</div>
</div>
</div>
</div>
</div>
var animating = false;
var clickedDiv, prevDiv, distance;
$('#off_wrap').on('click', '.package', function (e) {
e.stopPropagation();
if(animating == false) {
animating = true;
clickedDiv = $(this).closest('.package'),
prevDiv = $("#off_wrap > :first-child"),
distance = clickedDiv.offset().left - prevDiv.offset().left;
if (!clickedDiv.is(":first-child")) {
$.when(clickedDiv.animate({
left: -distance
}, 2000),
prevDiv.animate({
left: distance
}, 2000)).done(function () {
prevDiv.css('left', '0px');
clickedDiv.css('left', '0px');
//clickedDiv.css('width', $(window).width() - (clickedDiv.offset().left * 2));
clickedDiv.css('z-index', '10000000');
clickedDiv.css('overflow', 'visible');
clickedDiv.find(".inner_package").animate({width: 260}, 2000); //regullo kte
prevDiv.insertBefore(clickedDiv);
clickedDiv.prependTo("#off_wrap");
animating = false;
});
} else {
clickedDiv.css('z-index', '1000');
clickedDiv.find(".inner_package").css('transition', 'all 2s ease-in');
clickedDiv.find(".inner_package").css('width', '260px');
}
}
});
$(document).click(function() {
animating = false;
if(animating == false) {
clickedDiv.css('z-index', '1');
clickedDiv.find(".inner_package").css('transition', 'all 2s ease-in');
clickedDiv.find(".inner_package").css('width', '60px');
animating = false;
}
});
.internet {
text-align:center;
background: none repeat scroll 0% 0% rgba(248, 0, 140, 0.5);
padding-bottom:10px;
position: relative;
}
.internet .package {
display: inline-block;
/*border: 1px solid #FFFC00;*/
height: 60px;
width: 60px;
border-radius: 30px;
margin: 20px;
background:#fff;
color: rgba(0, 178, 248, 1);
position: relative;
cursor: pointer;
vertical-align:middle;
}
.inner_package {
display: inline-block;
width: 60px;
transition: all 2s ease-in;
background: #fff;
border-radius: 30px;
height: 60px;
}

It looks like you've put a lot of code in already attempting to fix the issue. I'm also a little confused as to what the issue is, as your jsFiddle doesn't give me trouble with clicking during the animation. Perhaps it's only certain situations you're speaking of.
Either way, I saw this.
$(document).click(function() {
animating = false;
if(animating == false) {
clickedDiv.css('z-index', '1');
clickedDiv.find(".inner_package").css('transition', 'all 2s ease-in');
clickedDiv.find(".inner_package").css('width', '60px');
animating = false;
}
});
That animating = false; both before the if statement and inside the if statement function seems redundant, and I suspect one of them needs to read animating = true; Let me know if that fixes your problem or not.
UPDATE: While I don't understand the animations themselves, I can say this. Your using animation as a control against multiple animations running. You have a statement that seems like it might be your problem.
if(animating == false) {
animating = true;
//do stuff
animating = false;
}
This may be your problem. Try getting more specific logic. like
if(animatingOne == false && animatingTwo == false && animatingThree == false) {
//logic to find out which animation is triggered
//turn the appropriate animation variable to true
//turn if off when done
}
If this doesn't work, keep playing with logic. I suspect that one variable animating is unable to accommodate the complexity of what you're doing.

Related

CSS transition creating problem in JavaScript? [duplicate]

Consider such div:
<div id="someid"></div>
And it's style:
#someid {
transition: background-color 10s ease;
background-color: #FF0000;
height: 100px;
width: 100px;
}
#someid:hover {
background-color: #FFFFFF;
}
I want to have a possibility to detect state (currently animating or not) of #someid via JS and/or end animation if that's possible. I've tried a thing from this answer:
document.querySelector("#someid").style.transition = "none";
but it didn't work for currently animating element.
The point is I need to detect whether element is animating now and if so, wait for animation to end or end it immediately, otherwise do nothing
I've already found transitionend event, but using it I can't detect whether element is animating at the moment.
You can listen to transition event and remove it on demand:
const el = document.getElementById('transition');
let isAnimating = false;
el.addEventListener('transitionstart', function() {
isAnimating = true;
});
el.addEventListener('transitionend', () => {
isAnimating = false;
});
el.addEventListener('transitioncancel', () => {
isAnimating = false;
});
function removeTransition(checkIfRunning) {
if (checkIfRunning && !isAnimating) {
return;
}
el.style.transition = "none";
}
#transition {
width: 100px;
height: 100px;
background: rgba(255, 0, 0, 1);
transition-property: transform background;
transition-duration: 2s;
transition-delay: 1s;
}
#transition:hover {
transform: rotate(90deg);
background: rgba(255, 0, 0, 0);
}
<div id="transition">Hello World</div>
<br />
<button onclick="removeTransition(false)">Remove Transition</button>
<br />
<br />
<button onclick="removeTransition(true)">Remove Transition on if running</button>

Jquery Resize Div with Toggle Button

I am building small private projects to learn jquery and currently I am stuck.
The Goal is to click a button and then my menu and my main content area should resize; when I click again it should resize itself back to normal.
The first part does work but the second part "jumps" down - I do not know why.
Here is my JSFiddle: https://jsfiddle.net/ne1mb706/1/
HTML:
<div><button id="show_hide_button">click me</button></div>
<div id="some_box"></div>
<div id="some_other_box"></div>
CSS:
html, body {
margin: 0;
padding: 0;
}
#some_box {
background: #fc0;
width: 25%;
height: 100px;
float:left;
}
#some_other_box {
background: #0cf;
width: 75%;
height: 100px;
float:left;
}
JQuery 3.4.1:
var collapsed = false;
$('#show_hide_button').click(function() {
if(!collapsed){
$('#some_box').animate({width: '0%'});
$('#some_other_box').animate({width: '100%'});
} else {
$('#some_box').animate({width: '25%'});
$('#some_other_box').animate({width: '75%'});
}
collapsed = !collapsed;
});
Thanks for any help :)
You must start with the visible one to animate work properly:
var collapsed = false;
$('#show_hide_button').click(function() {
if(!collapsed){
$('#some_box').animate({width: '0%'});
$('#some_other_box').animate({width: '100%'});
} else {
$('#some_other_box').animate({width: '75%'});
$('#some_box').animate({width: '25%'});
}
collapsed = !collapsed;
});

Javascript | How to stop a function that is running on a website

So, I've got a script that allows the user that goes on my website to activate like a rain feature. But I want them to be able to turn it off? The thing is that I don't have a clue on how to do this and I've tried many different things like break, return, some timeout thing, but nothing has given result, so I'm turning to you people who are smart and know this more then I do :)
Here is the script and I activate the script from a button press with onclick event.
var amountOfDrops = 150;
var started = false;
function randRange( minNum, maxNum) {
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);}
// function to generate drops
function createRain() {
if (started === false){
for( i=1;i<amountOfDrops;i++) {
var dropLeft = randRange(0,2400);
var dropTop = randRange(-1000,1400);
$('.rain').append('<div class="drop" id="drop'+i+'"></div>');
$('#drop'+i).css('left',dropLeft);
$('#drop'+i).css('top',dropTop);
}
console.log("Start");
console.log(started);
started = !started; //flips the bool to stop
}else{
console.log("Shut down");
console.log(started);
started = !started; //flips the bool to start
return false;
}}
I have searched around on the internet but I can't find anything about it so help is greatly appreciated.
EDIT(1)
So, let me fill in some gaps.
This is my CSS for it:
.drop {
background:-webkit-gradient(linear,0% 0%,0% 100%, from(rgba(13,52,58,1) ), to(rgba(255,255,255,0.6)) );
background: -moz-linear-gradient(top, rgba(13,52,58,1) 0%, rgba(255,255,255,.6) 100%);
width:1px;
height:89px;
color: #5cb1d1;
position: absolute;
bottom:200px;
-webkit-animation: fall .63s linear infinite;
-moz-animation: fall .63s linear infinite;
}
/* animate the drops*/
#-webkit-keyframes fall {
to {margin-top:900px;}
}
#-moz-keyframes fall {
to {margin-top:900px;}
}
This is how i call it in the html code:
<script type="text/javascript" src="scripts/Rain.js"></script>
<button onclick="createRain()">Start Rain</button>
I think we can solve this problem using setInterval(). It works for me just check it out.
var amountOfDrops = 150;
var started = false;
function randRange( minNum, maxNum) {
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);}
// function to generate drops
function createRain(started) {
if (started === false){
for( i=1;i<amountOfDrops;i++) {
var dropLeft = randRange(0,2400);
var dropTop = randRange(-1000,1400);
$('.rain').append('<div class="drop" id="drop'+i+'"></div>');
$('#drop'+i).css('left',dropLeft);
$('#drop'+i).css('top',dropTop);
}
}else{
started = !started; //flips the bool to start
return false;
}}
$(document).on("click",".start",function(){
started = false;
setInterval(function(){
createRain(started)
},200)
})
$(document).on("click",".end",function(){
started = true;
setInterval(function(){
createRain(started)
},200)
$(".drop").remove()
})
body{
background-color: #000000;
width: 100%;
overflow: hidden;
}
.btn{
border: 1px solid #ffffff;
color: #ffffff;
background-color: transparent;
margin: 20px auto;
padding:5px 20px;
}
.btn:hover{
color: #eeeeee;
}
.drop{
background-color: #000;
width: 1px;
height: 3px;
background-color: #ffffff;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button class="btn end">End</button>
<button class="btn start">Start</button>
</div>
<div class="rain">
</div>
i have the same problem,
you can try to add a timer to your function
and you can use :
$('#someElement').click(function(){
// Clear the timeout
clearTimeout(timer);
});
You could try to make a setInterval and then have a setTimeout for a clearInterval. Just a thought and this could be in or outside the function. Also, I'm pretty sure that JavaScript doesn't execute the console.log() and flips the boolean until the for statement is done. So the best way to go is a setInterval then have a clearInterval, whether a setTimeout or just a click of the button.

How to create a condition for scrolling below a point, and fire the function just once. instead of every time you scroll below that point

I'm trying to make the header fade out, then slide back in when you scroll past 100px, but the function fires every time you scroll anywhere past that point.
I don't want that to happen, I want it so that the function fires only once when you scroll past it and if you scroll again, even if you're past that point, nothing happens.
Check out my fiddle: http://jsfiddle.net/bazzle/6ykyjm0p/2/
Thanks in advance.
<header>
<div class="top">
This is the header
</div>
This is the point function should work.
</header>
html {
height: 200%;
}
header {
background-color: blue;
color: white;
width: 100%;
height: 300px;
}
.top{
height: 100px;
width: 100%;
border-bottom: 1px solid white;
display: block;
}
var stickyheader = function(){
if ($(window).scrollTop() > 100) {
$('header').hide(50, function(){
$(this).slideDown(1000);
});
}
else {
}
};
$(window).on('scroll',function(){
stickyheader();
});
Hi you can use a global variable as a flag to prevent the script from firing.
var flag = 0;
var stickyheader = function() {
if ($(window).scrollTop() > 100) {
if (flag == 0) {
$('header').hide(50, function() {
$(this).slideDown(1000);
flag = 1;
});
}
} else {
}
};
$(window).on('scroll', function() {
stickyheader();
});
html {
height:200%;
}
header {
background-color:blue;
color:white;
width:100%;
height:300px;
}
.top {
height:100px;
width:100%;
border-bottom:1px solid white;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="top">This is the header</div>This is the point function should work.</header>
You can also reset flag = 0; in the else case if you want the code to execute everytime the user scroll beyond the point.
Hope this help.

JQuery animate() not working as intended in conjunction with removeClass()

I've been trying to implement my own carousel as a way to teach myself javascript and have come across a problem where the animation prior to my removeClass call doesn't occur but the animation for bringing in the next element works as intended.
I realize this sounds quite vague so I've reproduced my problem with jsfiddle: http://jsfiddle.net/f57N3/
I've also included the relevant code below. Any help would be greatly appreciated!
HTML:
<div class="button-container">
<button id="b2">Next</button>
</div>
<div class="container">
<div class="box active-box" id="box1">
thingy
</div>
<div class="box" id="box2">
other thingy
</div>
<div class="box" id="box3">
another thingy
</div>
</div>
CSS:
.box{
display: none;
position: relative;
opacity: 0;
width: 350px;
height: 200px;
background-color: blue;
color: white;
border: 5px solid black;
}
.active-box{
display: block;
opacity: 1;
}
.container{
width: 850px;
height: 500px;
margin: 0px auto;
background-color: #003399;
}
Javascript:
// Functionality for 'Next' button
$("#b2").click(function(){
var thisBox = $(".active-box");
var nextBox = thisBox.next();
if(nextBox.length == 0){
nextBox = $(".box").first();
}
// Set pre-animation conditions
thisBox.css("margin-left", "0px");
thisBox.css("opacity", "1");
// Animate this box and remove active class
thisBox.animate({marginLeft: "-=300px", opacity: "0"}, 800).removeClass("active-box");
//Set pre-animation conditions
nextBox.css("margin-left", "300px");
nextBox.css("opacity", "0");
// Animate this box and add active class
nextBox.animate({marginLeft: "-=300px", opacity: "1"}, 800).addClass("active-box");
});
Any help would be greatly appreciated!
Animate has a complete function you can pass to it http://api.jquery.com/animate/
What was happening was that the removeClass was firing straight away. only removing in the complete seems to solve that. Also moving the following into that makes it run smoother.
// Functionality for 'Next' button
$("#b2").click(function () {
var thisBox = $(".active-box");
var nextBox = thisBox.next();
if (nextBox.length == 0) {
nextBox = $(".box").first();
}
// Set pre-animation conditions
thisBox.css("margin-left", "0px");
thisBox.css("opacity", "1");
// Animate this box and remove active class
thisBox.animate({
marginLeft: "-=300px",
opacity: "0"
}, 800, 'swing', function () {
thisBox.removeClass("active-box");
//Set pre-animation conditions
nextBox.css("margin-left", "300px");
nextBox.css("opacity", "0");
// Animate this box and add active class
nextBox.animate({
marginLeft: "-=300px",
opacity: "1"
}, 800).addClass("active-box");
})
});
Demo: http://jsfiddle.net/robschmuecker/f57N3/1/
You can do this maybe :
Javascript :
$("#b2").click(function(){
var thisBox = $(".active-box");
var nextBox = thisBox.next();
if(nextBox.length == 0){
nextBox = $(".box").first();
}
// Set pre-animation conditions
thisBox.css("margin-left", "0px");
thisBox.css("opacity", "1");
// Animate this box and remove active class
thisBox.animate({marginLeft: "-=300px", opacity: "0"}, 800);
thisBox.removeClass("active-box");
//Set pre-animation conditions
nextBox.css("margin-left", "300px");
nextBox.css("opacity", "0");
// Animate this box and add active class
nextBox.animate({marginLeft: "-=300px", opacity: "1"}, 800);
nextBox.addClass("active-box");
});

Categories