'Safari pauses all animation on redirect / form submission
I have an animation that triggers when a link is clicked. It is a jQuery animation that enlarges a div then fades out. To ensure speed, at the exact same time that the link is clicked, the redirect is fired off. This has to happen and I cannot put the redirect in the success function of jQuery's animate(). This redirect is done via a form submission. On Chrome, Firefox, and IE it works as expected, the animation plays and if the page loads entirely before the finish of the animation, it redirects but the animation does play.
On Safari (primarily testing on iPad), as soon as the link is clicked, the page seemingly 'freezes' and the animation fails to execute. There are also GIF's that are on the screen at page load, and if I click a link while those GIF's are on screen and animating, they pause as well. I have seen a post that says to set a timeout, apply styling, then submit, but the problem is that although the HTML will apply that CSS style, it still freezes the screen, and they are not dealing with animation, just static CSS styling.
Here is some example code to show the method of how I am accomplishing this (it is not tested just trying to illustrate my point, so there may be missing parts or syntax errors):
var someData = 'foo'; //This value is irrelevant, just there for syntactical consistency.
$("#link").on("click", function() {
var form = $("<form method='POST'></form>");
form.attr("action", "http://someurl.com");
var input = $("<input type='hidden'/>");
input.val(someData);
form.append(input);
$(document.body).append(form);
form.submit();
//Form has been submitted, now run a short animation for the remaining life of the current page
$(this).animate({width: "100px", height: "100px", opacity: "0"}, 150);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="link" style="width: 100px; height: 100px; background-color: #FFF">Click Me</div>
Essentially, I need to make sure that once the Safari browser begins to load a new page / link, it does not stop updating the current page. This sounds like a problem in Safari from what I have seen, but this issue has also not been run into very commonly across the web as I have seen. There are posts dealing with GIF animations, but this is a CSS style animation.
Thanks for any help!
Solution 1:[1]
What I have found is that Safari actually pauses all animations as soon as the pagehide event is fired, whenever the browser begins loading a new page.
After pagehide, it won't even allow CSS changes such as showing a spinner that was previously hidden.
In order to show the spinner before the pagehide event fires, I needed to add listeners for a[href] clicks and ajaxComplete events.
My guess is that Safari does this to enhance performamce by focusing all available CPU and GPU power to the rendering of the next page.
I think this is a bit extreme, and unfortunate for UX where in many mobile web applications we use spinner animations at page unload to show the user something is happening during the few seconds while a new page is being fetched.
I have so far not found a way to preserve motion animation during page unload; at best the spinner appears frozen but still shows up... a possible workaround is to use a static message to indicate it's "Loading..."
Solution 2:[2]
You could use a setTimeout to go to the link after the animation.
var someData = 'foo'; //This value is irrelevant, just there for syntactical consistency.
$("#link").on("click", function() {
setTimeout(doThisAfterTimeExpires,2000);
$(this).animate({width: "100px", height: "100px", opacity: "0"}, 150);
});
function doThisAfterTimeExpires(){
var form = $("<form method='POST'></form>");
form.attr("action", "http://someurl.com");
var input = $("<input type='hidden'/>");
input.val(someData);
form.append(input);
$(document.body).append(form);
form.submit();
}
Solution 3:[3]
Safari complains that it can't find the variable someData, it is trying to set the value of the input to the value of a variable that does not exist and stops executing that portion of the page's JavaScript.
[Error] ReferenceError: Can't find variable: someData
Just create the variable like this:
// [snip]
var input = $("<input type='hidden'/>");
var someData;
input.val(someData);
// [snip]
and it will work in Safari.
Solution 4:[4]
Write the code for animation before form submission. Perform form submission after some time. That is:
var someData = 'foo'; //This value is irrelevant, just there for syntactical consistency.
$("#link").on("click", function(e) {
//Write your code for animation at first.
$(this).animate({width: "100px", height: "100px", opacity: "0"}, 150);
//write the code for form submission
setTimeout(function() {
var form = $("<form method='POST'></form>");
form.attr("action", "http://someurl.com");
var input = $("<input type='hidden'/>");
input.val(someData);
form.append(input);
$(document.body).append(form);
form.submit();
}, 1000);
});
Solution 5:[5]
Possibly use some Ajax to load the new page in a hidden frame while the animation is still going. When it finishes loading, do a normal redirect to the same URL. Then hopefully it would be an instant redirect since the new page may then be cached and its underlying query already processed.
Solution 6:[6]
I had this issue for a long time and tested many differents ways.
I noticed that you still can use css animations, this mean you can still have an nice effect while safari is loading.
But, this require that your animations is not using any delays, Animation have to start as soon as the form is submitted.
For example, I wanted to have 3 car, appearing one after the other, while the page is loading.
As I was using a delay for each car before animation start, only the first one was appearing, then the animations stop, and car2, car3 never appeared.
But, when I removed the delay of the second and third car, this work fine, even if the animation is long.
This mean :
Animation delayed for 1s : Fail, don't even appear Animation starting at 0s : Works, even if animations duration is above 5s.
So, I assume Safari is stopping all animations, except those already launched
This worked for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | JD Smith |
| Solution 2 | hackdotslashdotkill |
| Solution 3 | Niklas Brunberg |
| Solution 4 | Sukanya Purushothaman |
| Solution 5 | user1946932 |
| Solution 6 | Bananier |
