So far, I have a pretty decent code to animate a center box. For some reason, when I preview this on different browsers and computer (Mac and PC) I get different results. One may show a faster animation speed, while the other is perfect. I have also noticed that when the box is being animated from left to right, there is a stutter, and the animation jerks. I can't really explain it more than that. My code is below:
$(document).ready(function(){
isAnimating = false;
$('.wrapper').on('click', '.arrow-left', function() {
if(isAnimating) return;
isAnimating = true;
var $current = $(this).parents('.signupBox');
var $next = $(this).parents('.signupBox').next();
$current.stop(true,true).animate({
left: "200%"
}, 500, 'linear', function() {
$current.css({
left: "-200%"
}).appendTo('.wrapper'); // move to end of stack
$next.css({
left: "-200%"
}).stop(true,true).animate({
left: "0%"
}, 500, 'linear', function() {
isAnimating = false;
});
});
}).on('click', '.arrow-right', function() {
if(isAnimating) return;
isAnimating = true;
var $current = $(this).parents('.signupBox');
var $next = $(this).parents('.signupBox').siblings().last();
$current.stop(true,true).animate({
left: "-200%"
}, 500, 'linear', function() {
$current.css({
left: "200%"
});
$next.prependTo('.wrapper') // move to front of stack
.css({
left: "200%"
}).stop(true,true).animate({
left: "0%"
}, 500, 'linear', function() {
isAnimating = false;
});
});
});
});
Some CSS:
.signupBox:first-child {
display: block;
}
.signupBox {
display: none;
}
.wrapper
{
overflow: hidden;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
position: absolute;
}
Here's a JSFiddle showing what happens, hopefully you can see what's the issue from there.
Then animation from right to left (click on the < symbol and you will see a slign change in speed.
Different browsers could have different results when using JS and css transitions, it actually depends on your machine speed, browser speed as well. It could depend on how many opened tabs you have in each browser, browsers plugins could freeze animations as well. Other JS events as well.
I have tested your code in Chrome, FF (wasn't able to check it in IE11, it seems there are JS errors on jsfiddler using jQuery). Didn't mentioned something strange.
I could recommend to use Greenshock JS animating library. http://www.greensock.com/get-started-js/
They say it's x20 times faster jQuery animate. But i think actually may be in 2,3 )
That libruary is based on Flash library that was used by Action Script coders to create beauty animations in Flash.
Related
I have a function that checks if there are any errors on the page and auto scrolls to them. The problem that I'm having is it scrolls up to them but then comes back down to where it was before. I'd like it to scroll up and stay there.
$(".submit_button").click(function (event) {
event.preventDefault();
var errorElements = $(".error").filter(":visible");
if (errorElements.size() > 0) {
target_top = $(errorElements).offset().top;
$('html, body').animate({
scrollTop: target_top
}, 800);
}
return false;
});
The problem is in your selector. I know why it's done. Any web dev that's been in this long enough has been using that for as much cross browser compat as possible, and yet still encountered this issue. The problem is, you're calling animate:scroll on 2 items consecutively using this selector.
The better way, in short, would be to check if it is a WebKit browser or not. Reason being is that non-WebKit tend to use html whereas WebKit browsers tend to use body (and sometime html). This can cause such confusion as you face now.
The simple short term solution is to use something like /WebKit/i.test(navigator.userAgent) in your click callback. This will help you assign only one selector to the animate call.
Example
var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html';
$(selector).animate( // ...
Test Snippet
$(function() {
// simply to make filler divs for scrolling
for (var i=0;i<10;i++) $('<div />', { 'id': 'div'+i, 'style': 'background-color: '+String.randColorHex()+';' }).append($('.temp').clone().removeClass('temp')).height($(window).height()).appendTo($('body'));
/*------------------------------------------*/
/***S*O*L*U*T*I*O*N***/
var divID = 0;
function btnCheck() { // IGNORE, simply to turn buttons on and off when reaching end
$('#btnScrollDown').prop('disabled', divID>=9);
$('#btnScrollUp').prop('disabled', divID<=0);
}
$(document)
.on('click', '#btnScrollDown', function() {
if (divID < 10) {
divID++;
// broke everything down so it's easy to see. You can shorten this in a few ways.
/*THIS HERE-> */var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html',
scrollSelector = '#div' + (divID),
scrollTop = $(scrollSelector).offset().top
props = { scrollTop: scrollTop },
time = 800;
$(selector).animate(props, time);
// simply to turn buttons on and off when reaching end
btnCheck();
}
})
.on('click', '#btnScrollUp', function() {
if (divID > 0) {
divID--
// broke everything down so it's easy to see. You can shorten this in a few ways.
/*THIS HERE-> */var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html',
scrollSelector = '#div' + (divID),
scrollTop = $(scrollSelector).offset().top
props = { scrollTop: scrollTop },
time = 800;
$(selector).animate(props, time);
// simply to turn buttons on and off when reaching end
btnCheck();
}
});
});
html, body, div { margin: 0; padding: 0; width: 100%; }
.buttons { display: inline-block; left: 1em; position: fixed; text-align: center; top: 1em; }
button { margin: .25em; padding: .1em .3em; width: 100%; }
.temp { dislpay: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/JDMcKinstry/String.randColorHex/0c9bb2ff/String.randColorHex.js"></script>
<section class="buttons">
<button id="btnScrollUp" disabled>Scroll To Next Div Up</button><br />
<button id="btnScrollDown">Scroll To Next Down</button>
<sub><i>this isn't fully managed, only use buttons to scroll!</i></sub>
</section>
<table class="temp"><tr><td></td></tr></table>
I am trying to achieve a situation where an animation is triggered if an element has a particular background = url(" "). I am using velocity.js as the animation plugin and am able to achieve this no problem on all browser except IE, in which it fails to recognise the background url in the if statement.
I have two examples in the code below.
The first one (the orange square) uses -
if (box.style.background == "orange")
{ run(); }
to determine whether to run the animation. IE is fine with this.
However the second (the pink triangle) uses -
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat")
{ runTriangle(); }
to determine whether to run the animation. IE is the only browser not to run this.
Does anyone have any idea where I'm going wrong here.
JS Fiddle example
HTML
<div id="box"></div>
<div id="triangle"></div>
CSS
#box {
width: 100px;
height: 100px;
position: absolute; }
#triangle {
width: 200px;
height: 100px;
top: 120px;
position: absolute;
z-index: 4; }
JS
window.setInterval(function runAll() {
var box = document.getElementById('box');
box.style.background = "orange";
function run() {
Velocity(box, {left: 300}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
Velocity(box, {left: 10}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
}
if (box.style.background == "orange")
{ run(); }
var triangle = document.getElementById('triangle');
triangle.style.background = "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat";
function runTriangle() {
Velocity(triangle, {left: 300}, {easing: "easeInOutQuad", duration: 1000, delay: 200});
Velocity(triangle, {left: 10}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
}
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat")
{ runTriangle(); }
}, 1000);
runAll();
The URLs in IE are different from webkit and/or Gecko, it is not safe to base your logic on the url paths.
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat" || triangle.style.background == 'url("http://garyvoss.co.uk/images/triangle.svg") no-repeat' )
{ runTriangle(); }
I've managed to find a convoluted way around the issue.
Using .match I can identify a section of the url path and apply that to the if statement so that if that section is present then the animation runs.
I've create a third example (the green circle) in this JS Fiddle that shows how it works.
var str = circle.style.background;
var res = str.match(/circle/g);
document.getElementById("check").innerHTML = res;
if (document.getElementById("check").innerHTML === "circle")
{ runCircle(); }
I have the back to top button that appears when you reach a point on the page, which is working fine, however, when it appears the text is on two lines until the box has finished the animation to appear. So, is there anyway to prevent this? What I mean by the animation is: btt.show('slow');
Code:
$(document).ready(function () {
var btt = $('.back-to-top');
btt.on('click' , function(e) {
$('html, body').animate({
scrollTop: 0
}, 500);
btt.hide('slow');
e.preventDefault();
});
$(window).on('scroll', function () {
var self = $(this),
height = self.height(),
top = self.scrollTop();
if (top > 500) {
btt.show('slow');
} else {
btt.hide('slow');
}
});
});
Example: http://codepen.io/Riggster/pen/WvNvQm
The problem is caused by animating the width of a box, I think it might be better to animate the position of it instead, but - even better - lets use CSS animations!
$(window).on('scroll', function () {
if ($(window).scrollTop() >= 500) {
$(".button").addClass('show');
} else {
$(".button").removeClass('show');
}
});
#wrapper {
width: 100%;
height: 2000px;
}
.button {
position: fixed;
bottom: 50px;
right: -100px;
/* You might still need prefixes here. Use as preferred. */
transition: right 500ms;
}
.button.show {
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="wrapper">
<div class="button">Here's my button!</div>
</div>
I've defined your button as hidden by default, by giving it a position of right: -100px. When we hit the correct scroll position, we add the class show and that triggers the animation performed by CSS and not javascript, as we have the transition property for the property right defined - that way the browser does the heavy lifting.
Toggling show/hide alters your elements width. You either have to put it in a container with display: inline
Or more ideally you might want to change show/hide to jQuery fadeIn() / fadeOut() which is more appropriate for "Back to Top" indicators.
Here is your codepen example modified with inline container:
http://codepen.io/anon/pen/MwWweY
I have this semi-slider-style UI where new terms are added in from the left: http://jsfiddle.net/v4v5cvkz/. I'm using the jQuery prependTo function to do this. My issue is that I want the terms that are already displayed to perform an animated slide to the right when a new term gets added, rather than suddenly "appear" in the correct position. I did try adding a "displayed" class to terms that had successfully shown up, and tried adding a slide-to-right animation after that, but that didn't quite achieve the effect I was going for (the "displayed" objects were moved much further to the right than I expected).
Here is the problematic code (you'll probably want to view the fiddle to see it in context though):
function addToStream(term, delay) {
setTimeout(function(){
$("<div />")
.addClass("stream_term")
.html(term)
.css({
opacity: 0
})
.prependTo("#stream_terms")
.animate({opacity:1},
{ duration: 1000,
complete: function() {
$(this).addClass("displayed");
}
});
}, delay);
}
Any help here would be greatly appreciated. Thank-you!
*Note: I have access to jQuery UI in my code, though it isn't linked in the fiddle. Also, if anyone knows of a plugin that can do this sort of thing better than I can, please let me know. The closest one I was able to find was Fraction Slider, but I didn't find it obvious how to create a similar UI with it (it might also be overkill for my purposes).
Here's a way to do it:
function addToStream(term, delay) {
setTimeout(function(){
var newDiv = $("<div />");
newDiv.addClass("stream_term")
.html(term)
.css({
opacity: 0,
display: 'none'
}).prependTo("#stream_terms");
var width = newDiv.width();
var height = newDiv.height();
newDiv.css({
width: 0,
height: height,
display: 'inline-block'
})
.animate({
width: width,
margin: '0 10px',
padding: '5px 10px'
}, 1000)
.animate({opacity: 1}, 1000, function(){
$(this).addClass("displayed");
});
}, delay);
}
It also needs the following CSS changes:
.stream_term {
padding: 0;
margin: 0;
overflow: hidden;
}
DEMO: http://jsfiddle.net/StathisG/hqg29p6r/1/
I have a navigation bar that sticks out a little bit from the right edge of the screen. I want it so when you hover on the div, it slides left 550px out of the right side of the browser. I'm using jquery's animate function and I got it to animate properly when hovered, but I can't get it to slide back to the right when you stop hovering on it.
I'm very new to javascript/jquery and I feel like I'm missing something simple...
$(document).ready(function(){
$("#nav").hover(function() {
$(this).animate({
right: "0px",
}, 800 );
(function() {
$(this).animate({
right: "-550px",
}, 800 );
});
});
});
And here's #nav's css:
#nav {
position: absolute;
right: -550px;
min-width: 300px;
top: 10px;
height: 50px;
background-color: #B30431;
}
The code has some syntax errors. The code should be :
$(document).ready(function(){
$("#nav").hover(
function() {
$(this).animate({ right: "0px" }, 800 );
},
function() {
$(this).animate({ right: "-550px" }, 800);
}
});
});
Good Luck !!
You have made your hover function complicated, you have wrapped the function with () and your function is not executed.
$(document).ready(function() {
$("#nav").hover(function() {
$(this).animate({ right: "0px" }, 800);
}, function() {
$(this).animate({ right: "-550px" }, 800);
});
});
One option, which we use a lot for our animation, is to make a css class that contains that animation, and then ise the .addClass() method to trigger the animation. Its fast, and its browser compatible. You could also use pure css for this.
You could try this...Demo
$(document).ready(function(){
$("#nav").mouseover(function(){
$(this).delay(200).animate({right: "0px"}, 800 );
// Added a 200ms delay to prevent quick accidental mouse overs triggering animation.
});
$("#nav").mouseout(function(){
$(this).clearQueue();
// Gives the user the ability to cancel the animation by moving the mouse away
$(this).animate({right: "-550px"}, 800 );
});
});