Safari在重定向/表单提交时暂停所有动画

Safari pauses all animation on redirect / form submission

本文关键字:暂停 动画 表单提交 重定向 Safari      更新时间:2024-06-28

我有一个动画,当点击链接时会触发。这是一个jQuery动画,它放大div然后淡出。为了确保速度,在点击链接的同时,会触发重定向。这是必须的,我不能将重定向放在jQuery的animate()的成功函数中。此重定向是通过表单提交完成的。在Chrome、Firefox和IE上,它按预期工作,动画会播放,如果页面在动画完成之前完全加载,它会重定向,但动画确实会播放。

在Safari上(主要在iPad上测试),只要点击链接,页面就会"冻结",动画也无法执行。页面加载时,屏幕上也会出现GIF,如果我在这些GIF出现在屏幕上并设置动画时单击链接,它们也会暂停。我看到一篇帖子说,设置超时,应用样式,然后提交,但问题是,尽管HTML会应用该CSS样式,但它仍然会冻结屏幕,而且他们处理的不是动画,而是静态CSS样式。

以下是一些示例代码,展示了我如何实现这一点的方法(它不是为了说明我的观点而测试的,所以可能会有缺失的部分或语法错误):

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>

从本质上讲,我需要确保Safari浏览器开始加载新页面/链接后,不会停止更新当前页面。从我所看到的情况来看,这听起来像是Safari中的一个问题,但这个问题在网络上也没有像我看到的那样常见。有一些关于GIF动画的帖子,但这是一个CSS风格的动画。

谢谢你的帮助!

我发现,无论何时浏览器开始加载新页面,只要触发pagehide事件,Safari实际上就会暂停所有动画。

在pagehide之后,它甚至不允许CSS更改,比如显示以前隐藏的微调器。

为了在pagehide事件触发之前显示微调器,我需要为[href]点击和ajaxComplete事件添加监听器。

我的猜测是,Safari通过将所有可用的CPU和GPU能力集中到下一页的渲染上来提高性能。

我认为这有点极端,对用户体验来说是不幸的,在许多移动网络应用程序中,我们在页面卸载时使用微调器动画来向用户显示在获取新页面的几秒钟内发生的事情。

到目前为止,我还没有找到一种在页面卸载期间保留运动动画的方法;充其量旋转器看起来是冻结的,但仍然显示。。。一个可能的解决方法是使用静态消息来指示它是"正在加载…"

您可以使用setTimeout在动画之后转到链接。

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();
}

Safari抱怨找不到变量someData,它试图将输入的值设置为不存在的变量的值,并停止执行页面JavaScript的该部分。

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

只需创建这样的变量:

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

它将在Safari中工作。

在表单提交前编写动画代码。一段时间后执行表单提交。即:

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);
});

可能在动画仍在进行时使用一些Ajax将新页面加载到隐藏帧中。当它完成加载时,执行一个正常的重定向到相同的URL。然后希望这将是一个即时重定向,因为新页面可能会被缓存,其底层查询已经被处理。

我有这个问题很长一段时间了,并测试了许多不同的方法。

我注意到你仍然可以使用css动画,这意味着你在加载safari时仍然可以有很好的效果。

但是,这需要您的动画不使用任何延迟,动画必须在表单提交后立即开始。

例如,我想要3辆车,在加载页面时一辆接一辆地出现。

由于我在动画开始前对每辆车都使用了延迟,所以只有第一辆车出现,然后动画停止,car2、car3从未出现。

但是,当我去掉第二辆和第三辆车的延迟时,这项工作很好,即使动画很长。

这意味着:

动画延迟1秒:失败,甚至不出现动画从0s开始:有效,即使动画持续时间超过5s。

所以,我认为Safari正在停止所有动画,除了那些已经启动的动画

这对我很有效。

我遇到了同样的问题。不幸的是,使用setTimeout()的解决方案对我不起作用。由于提交延迟,CSS动画会启动,但当页面开始加载时会立即冻结。

所以我最终做的是一个特殊的动画,不那么动态,特别是对于safari浏览器:

var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if(isSafari){ // If Safari browser
  $("span#loading_without_spinner").css("display", "block"); // This span contains the text "Loading..."
}else{ // Other browsers
  $j("span.spinner").css("display", "block"); // This span contains my css svg animation
}

如果有人在页面加载过程中强制使用CSS动画,我仍然很感兴趣。