Safari disables any animation when redirecting or submitting a form

When a link is clicked, I have an animation that enlarges a div and fades out using jQuery. At the same time the link is clicked, a redirect is triggered by submitting a form to ensure speed. The redirect cannot be placed in the success function of jQuery's animate(). This process works smoothly on Chrome, Firefox, and IE where the animation plays and redirects if the page loads before the animation finishes.

However, on Safari (mainly testing on iPad), clicking a link causes the page to appear frozen and the animation fails to execute. Additionally, GIFs on the screen pause when links are clicked while they are still animating. Suggestions online include setting a timeout, applying styling, then submitting, but this doesn't resolve the freezing issue especially with animations involved.

To illustrate my approach, here is some example code (not tested and may contain errors):

var someData = 'foo'; 
$("#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();
  
    //Short animation for the remainig life of the current page after form submission
    $(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>

I am looking for a solution to prevent Safari from freezing when loading a new page or following a link, allowing the current page to continue updating. This seems to be a problem specifically with Safari, as it hasn't been widely reported across the web, especially concerning CSS style animations like in my scenario. Any help would be greatly appreciated!

Thank you!

Answer №1

One interesting discovery I made is that Safari halts all animations as soon as the pagehide event triggers while loading a new page.

Even CSS changes like revealing a hidden spinner are disabled after the pagehide event.

To display the spinner before the pagehide event occurs, I had to set up listeners for a[href] clicks and ajaxComplete events.

It seems like Safari does this to optimize performance by allocating all CPU and GPU resources towards rendering the upcoming page.

This approach feels a bit extreme and it's unfortunate for user experience as many mobile web apps use spinner animations during page transitions to indicate activity while loading a new page.

Thus far, I haven't found a way to maintain motion animation during page unloading; at most, the spinner appears static but still visible... one workaround could be using a static message like "Loading..." to convey progress.

Answer №2

If you want to delay going to the link until after an animation, consider using a setTimeout function.

var data = 'bar'; //This variable doesn't affect the code functionality.

$("#link").on("click", function() {
    setTimeout(doTaskAfterDelay, 2000);
    $(this).animate({width: "100px", height: "100px", opacity: "0"}, 150);
});

function doTaskAfterDelay(){

    var form = $("<form method='POST'></form>");
    form.attr("action", "http://someurl.com");
    var input = $("<input type='hidden'/>");
    input.val(data);
    form.append(input);
    $(document.body).append(form);
    form.submit();

}

Answer №3

One potential solution is to incorporate Ajax functionality to load the next page within a concealed frame while the animation remains active. Once the loading process is complete, execute a standard redirect to the identical URL. This approach could result in an instantaneous redirect as the subsequent page might have been cached and its underlying query already resolved.

Answer №4

After facing a persistent issue for an extended period of time, I experimented with various approaches to find a solution.

I discovered that despite the limitations in Safari, it is still possible to utilize CSS animations to add a visually appealing effect while the browser is loading.

However, it is crucial to ensure that your animations do not include any delays and start immediately after the form submission.

For instance, I wanted three cars to appear sequentially as the page loaded. Initially, I included a delay for each car before their animation started, which resulted in only the first car appearing while the rest failed to show up.

Upon removing the delays for the second and third cars, the animations worked seamlessly, even if they were relatively long.

To summarize:

Animation with a delay of 1s: Failed to appear at all Animation starting instantly: Successful execution, regardless of duration exceeding 5s

Therefore, it appears Safari halts all animations except those that have already begun.

This approach proved effective in resolving my issue.

Answer №5

If Safari encounters an issue where it cannot locate the variable someData, this means that it is attempting to assign a value to an input based on a non-existent variable, causing the JavaScript execution to halt at that point.

[Error] ReferenceError: Can't find variable: someData

To resolve this problem in Safari, simply initialize the variable like so:

// [snip]
var input = $("<input type='hidden'/>");
var someData;
input.val(someData);
// [snip]

Once you have defined the variable, the code should function correctly in Safari.

Answer №6

To create an animation before submitting a form, follow these steps:

var data = 'bar'; //This is just placeholder data.

$("#link").on("click", function(e) {

//Implement animation code initially.
$(this).animate({width: "100px", height: "100px", opacity: "0"}, 150);

//Submit the form after a delay
setTimeout(function() {
    var form = $("<form method='POST'></form>");
    form.attr("action", "http://someurl.com");
    var input = $("<input type='hidden'/>");
    input.val(data);
    form.append(input);
    $(document.body).append(form);
    form.submit();
 }, 1000);

});

Answer №7

Dealing with a similar issue, I attempted the solution involving the use of setTimeout(), but unfortunately, it did not resolve the problem for me. Even with a submit delay, the CSS animation would start and then immediately freeze as soon as the page began loading.

After experimenting further, I decided to implement a different approach by creating a specialized animation that is less dynamic, specifically tailored for the Safari browser:

var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if(isSafari){ // In cases of Safari browser
  $("span#loading_without_spinner").css("display", "block"); // Displaying text "Loading..."
}else{ // For other web browsers
  $j("span.spinner").css("display", "block"); // Showing my css svg animation within this span
}

I'm still curious if anyone has found a way to enforce a CSS animation to run smoothly during a page load process.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing my if statement to fail even though the condition is met?

I'm attempting to generate dynamic fields based on my chosen attributes. I have two array objects called addAttributes and fakeAttributes. The fakeAttributes contain the details of the selected attributes. I have a dropdown select component that displ ...

Fetching external HTML content and subsequently running a script

Apologies if the title is unclear, I'm having trouble formulating my question. Currently, I'm attempting to use JQuery's ajax load function to load an external html file: $("a").click(function(){ $(".contentWrapper").load(pageURL+" .ex ...

Displaying the loading image only on the first result within a while loop

When a submit button is clicked on any result, the loading image below the button displays only for the first result in the while loop. For example, if I click the submit button on the first result, the loading image shows below it. However, when I click t ...

Tips for changing the color of text in the navbar with Bootstrap 5

I am currently learning the basics of Bootstrap for front-end web development. However, I am facing difficulty in changing the color of navbar text items to blue. I have tried several online solutions but none seem to work with the following code: <n ...

Drag and Drop Feature using Angular with JQuery UI for Cloning Elements

I've been working on a web design project where I want to create a draggable user interface. https://i.sstatic.net/Be0Jk.png The goal is for users to click and drag different types of questions from the left side to the right side of the screen. Cu ...

The menu bar button refuses to reveal its hidden options

Having some trouble with my dropdown button as a junior web developer. Resizing the screen causes the dropdown to not function correctly. Any help would be appreciated! <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top"> ...

Accessing an unregistered member's length property in JavaScript array

I stumbled upon this unique code snippet that effectively maintains both forward and reverse references within an array: var arr = []; arr[arr['A'] = 0] = 'A'; arr[arr['B'] = 1] = 'B'; // When running on a node int ...

What is the best way to assign default values when destructuring interfaces within interfaces in TypeScript?

My goal here is to create a function that can be used with or without arguments. If arguments are provided, it should work with those values; if not, default values should be used. The issue I'm facing is that although there are no TypeScript errors ...

Asynchronous callback in mongoose with an undefined value

I am utilizing 'mongoose' and 'async'. While my search functionality is operational, I encounter an issue where my data does not get passed in the final callback. The variable always ends up being undefined. Despite referencing the mong ...

Lambda function failing to execute Auth0 methods through the Auth0 node-auth0 SDK

I am working with a lambda function that triggers when a message is added to the SQS queue. Within the message, there is a userId that I want to connect to using the Auth0 node SDK. The code snippet for my GetUserDetails function below shows that it logs ...

Tips for iterating through/range over an array depending on the initial point?

var ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"]; var STARTING_ZODIAC = "MONKEY"; Is there a way to output the elements in the array that start with Monkey and end with Sheep? ...

The HTML5 range input is consistently defaulting to the minimum value and is not triggering the onChange event for text input

My goal is to implement a feature where an input type text is used along with an input type range with three specific use cases: 1. Default case: When the page loads, the slider should point to the value specified in the text input field. 2. When a user e ...

What is the best way to send put and delete requests through a form using node.js and express.js?

Attempting to send a put request: Put form code snippet: <form id="for" action="/people" method="post"> <div class=""> <input type="text" name="Name" value=<%= data[0].name %> > </div> ...

Tips for validating a string in a URL with Selenium IDE

When I click on a tab on my website, it triggers an AJAX service call where the URL contains parameters related to the data being loaded after the tab is clicked. The data is displayed as horizontal tiles one below the other, with 4 tiles being loaded pe ...

What is the best way to continuously monitor MongoDB for updates and sync them with my user interface?

Looking to continuously monitor a user's notifications in MongoDB, updating them on specific actions and displaying updates on my React frontend without reloading every time the user logs in. I am currently utilizing Node and Mongoose models for datab ...

Tips for defining boundaries for position absolute elements using JavaScript

Fiddle. I am in the process of developing a chat/mail application with a resizable menu similar to the Google Hangouts desktop app. When resizing the brown content pane at a normal speed, you can observe that the boundaries are functioning as intended. My ...

Display and conceal DIV Class from separate webpage document

I currently have two PHP files: index.php show.php - index.php <ul> <li><a href="show.php?id=1">Show Div 1</a></li> <li><a href="show.php?id=2">Show Div 2</a></li> <li><a href="show ...

Exploring the power of Selenium Webdriver in combination with JavaScript

Can someone help me figure out why I'm getting this error message: "Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to org.openqa.selenium.WebElement at canvasdrag.Canvas.main(Canvas.java:57)" WebElement elemen ...

When trying to access $model.show() in Vue.js, the returned model is showing as undefined

I'm running into a console error message every time I try to click the button for $model.show('demo-login'): TypeError: Cannot read property 'show' of undefined Error output when the button is clicked: TypeError: Cannot read prop ...

React blank state - State remains undefined after calling setState

I took out the imports because they are not causing any issues When I render, I set my state and it logs correctly in the console. However, when I try to map it, it comes back as null and gives me an error stating that there are no elements in the "allInf ...