Ber*_*uez 5 javascript css mobile css-transitions css-animations
我正在尝试在我的网站上制作动画。我正在使用下面链接的类似版本的 jsfiddle 代码。在桌面上查看时,动画效果很好。然而,当在移动设备上查看时,特别是在我的 Chrome 浏览器上,出现了奇怪的延迟。当我在手机上打开 jsfiddle 时,它显示出完全相同的延迟。如果我重新启动 chrome 应用程序,延迟就会消失,很快就会恢复。
在 Safari 中不会出现此问题。
我有最新的 iPhone,运行 IOS 14.6 和 chrome V90。
https://jsfiddle.net/brodriguez98/e2bvwcja/33/
HTML:
<html>
<p style = 'margin-top: 100vh;'>above</p>
<img class = 'balltest show-on-scroll standard-push' src = 'http://www.pngall.com/wp-content/uploads/5/Sports-Ball-Transparent.png'/>
<img class = 'balltest show-on-scroll fade-in' src = 'http://www.pngall.com/wp-content/uploads/5/Sports-Ball-Transparent.png'/>
<p style = 'margin-bottom: 100vh'>below</p>
</html>
Run Code Online (Sandbox Code Playgroud)
CSS:
.balltest {
width: 50px;
}
.fade-in {
opacity: 0;
-webkit-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;
-moz-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;
-o-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;
transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 0.3s 0.25s ease-out;
will-change: transform, opacity;
}
.standard-push {
opacity: 0;
transform: translateY(4em);
-webkit-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out, translateZ(0);
-moz-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;
-o-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;
transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 0.3s 0.25s ease-out;
will-change: transform, opacity;
}
.is-visible {
transform: translateY(0);
opacity: 1;
}
Run Code Online (Sandbox Code Playgroud)
JavaScript:
var elementsToShow = document.querySelectorAll('.show-on-scroll');
$(window).scroll(function() {
Array.prototype.forEach.call(elementsToShow, function (element) {
if (isElementInViewport(element)) {
element.classList.add('is-visible');
} else {
element.classList.remove('is-visible');
}
});
});
// Helper function from: http://stackoverflow.com/a/7557433/274826
function isElementInViewport(el) {
// special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
(rect.top <= 0 &&
rect.bottom >= 0) ||
(rect.bottom >= (window.innerHeight || document.documentElement.clientHeight) &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight)) ||
(rect.top >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight))
);
}
Run Code Online (Sandbox Code Playgroud)
对于屏幕太小,我深表歉意,无法在我的手机上全屏显示 JSfiddle:
重新启动移动 Chrome 后动画立即工作: https://www.loom.com/share/ac6c843b90d2428bb875572d55e32959
动画很快就中断了(当我关闭/重新加载页面时): https://www.loom.com/share/e51cf88aa1a74aed8e4d1ed253e83ea0
这与我在使用移动 Chrome 浏览器的网站上看到的行为完全相同。
更新: 下面的答案都不适合我。我忘了提及这种行为也发生在文本上。另外,感谢您建议codesandbox,我分叉了您的代码,并通过删除图像使其变得更加简单,但我仍然在我的iphone chrome浏览器上得到相同的结果。我还尝试用 onload 函数包装所有内容,但这也不起作用。
目前我可以使用 JQuery 动画修复此问题,但我仍然希望 CSS3 过渡能够在我的网站上工作。
https://codesandbox.io/s/animation-test-forked-tqurn?file=/index.html
这看起来像是加载页面时的“竞争条件”问题。\nJS 在 IMG 请求完成之前运行。
\n要理解这个问题,有必要了解加载顺序:
\n加载/重新加载时,服务器响应文档 (*.html) 文件
\n浏览器开始解析响应(*.html)并为找到的每个资源启动新请求:
\n这些请求以不可预测的顺序完成。例如,大图像的加载时间可能比 *.css 文件长,...某些资源可能已经被浏览器缓存,并且根本不会\xc2\xb4t 启动请求,...
\n如果 *.js 文件的请求在IMG 请求完成之前height完成,则找不到该图像的渲染,并且新添加的 CSS 类无论如何is-visible都会启动transition...
一旦 IMG 请求完成(img 被渲染)。IMG 会触发内容重排。 \n需要重绘的元素(IMG)的持续过渡是“重置”,并从关键帧 0 开始。\n这可能可以解释您的问题。
\n以下 3 个选项可能可以解决您的问题:
\n在 CSS 中设置修复height并在 html 中添加类:
.myImg {\n width: 50px;\n height: 50px;\n}\nRun Code Online (Sandbox Code Playgroud)\n您还可以添加width和height作为 html 属性。即使 *.css 仍在加载,最终尺寸现在也可以在 JS 中使用...
<img height="50" width="50" class="..." src="...">\nRun Code Online (Sandbox Code Playgroud)\nsrc已设置并被height检测到 -onload为该图像设置一个事件(因为它尚未加载)src被设置为data-src属性,src一旦图像可用,将由 JS 设置。现在我们可以使用一个isLoaded(element)函数来排除.scroll()当前未完全加载的图像。
这是jsFiddle,或扩展下面的示例......
\nvar elementsToShow = document.querySelectorAll(\'.show-on-scroll\');\n$(window).scroll(function() {\n Array.prototype.forEach.call(elementsToShow, function (element) {\n if (isLoaded(element) && isElementInViewport(element)) {\n element.classList.add(\'is-visible\');\n } else {\n element.classList.remove(\'is-visible\');\n }\n });\n});\n\n[...elementsToShow].forEach((imgEl, i) => {\n if (\n imgEl.src &&\n imgEl.getBoundingClientRect().height\n ) {\n imgEl.dataset.isLoaded = true;\n console.log(`Img ${i} already loaded`);\n } else {\n console.log(`Img ${i} still loading... or should be lazyloaded`);\n\n imgEl.onload = function(e) {\n console.log(`Img ${i} finally loaded! onload event`);\n e.target.dataset.isLoaded = true;\n };\n\n if (imgEl.dataset.src) {\n console.log(`Img ${i} start lazy load...`);\n imgEl.src = imgEl.dataset.src;\n }\n }\n})\n\nfunction isLoaded(el) {\n return el.dataset.isLoaded\n}\nRun Code Online (Sandbox Code Playgroud)\nvar elementsToShow = document.querySelectorAll(\'.show-on-scroll\');\n$(window).scroll(function() {\n Array.prototype.forEach.call(elementsToShow, function (element) {\n if (isLoaded(element) && isElementInViewport(element)) {\n element.classList.add(\'is-visible\');\n } else {\n element.classList.remove(\'is-visible\');\n }\n });\n});\n\n[...elementsToShow].forEach((imgEl, i) => {\n if (\n imgEl.src &&\n imgEl.getBoundingClientRect().height\n ) {\n imgEl.dataset.isLoaded = true;\n console.log(`Img ${i} already loaded`);\n } else {\n console.log(`Img ${i} still loading... or should be lazyloaded`);\n\n imgEl.onload = function(e) {\n console.log(`Img ${i} finally loaded! onload event`);\n e.target.dataset.isLoaded = true;\n };\n\n if (imgEl.dataset.src) {\n console.log(`Img ${i} start lazy load...`);\n imgEl.src = imgEl.dataset.src;\n }\n }\n})\n\nfunction isLoaded(el) {\n return el.dataset.isLoaded\n}\nRun Code Online (Sandbox Code Playgroud)\r\nvar elementsToShow = document.querySelectorAll(\'.show-on-scroll\');\n$(window).scroll(function() {\n Array.prototype.forEach.call(elementsToShow, function(element) {\n if (isLoaded(element) && isElementInViewport(element)) {\n element.classList.add(\'is-visible\');\n } else {\n element.classList.remove(\'is-visible\');\n }\n });\n});\n\n[...elementsToShow].forEach((imgEl, i) => {\n if (\n imgEl.src &&\n imgEl.getBoundingClientRect().height\n ) {\n imgEl.dataset.isLoaded = true;\n console.log(`Img ${i} already loaded`);\n } else {\n console.log(`Img ${i} still loading... or should be lazyloaded`);\n \n imgEl.onload = function(e) {\n console.log(`Img ${i} finally loaded! onload event`);\n e.target.dataset.isLoaded = true;\n };\n \n if (imgEl.dataset.src) {\n console.log(`Img ${i} start lazy load...`);\n imgEl.src = imgEl.dataset.src;\n }\n }\n});\n\nfunction isLoaded(el) {\n return el.dataset.isLoaded\n}\n\n// Helper function from: http://stackoverflow.com/a/7557433/274826\nfunction isElementInViewport(el) {\n // special bonus for those using jQuery\n if (typeof jQuery === "function" && el instanceof jQuery) {\n el = el[0];\n }\n var rect = el.getBoundingClientRect();\n return (\n (rect.top <= 0 &&\n rect.bottom >= 0) ||\n (rect.bottom >= (window.innerHeight || document.documentElement.clientHeight) &&\n rect.top <= (window.innerHeight || document.documentElement.clientHeight)) ||\n (rect.top >= 0 &&\n rect.bottom <= (window.innerHeight || document.documentElement.clientHeight))\n );\n}Run Code Online (Sandbox Code Playgroud)\r\n.balltest {\n width: 50px;\n}\n\n.fade-in {\n opacity: 0;\n -webkit-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;\n -moz-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;\n -o-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;\n transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 0.3s 0.25s ease-out;\n will-change: transform, opacity;\n}\n\n.standard-push {\n opacity: 0;\n transform: translateY(4em);\n -webkit-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out, translateZ(0);\n -moz-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;\n -o-transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 1s 0.25s ease-out;\n transition: transform 4s 0.25s cubic-bezier(0, 1, 0.3, 1), opacity 0.3s 0.25s ease-out;\n will-change: transform, opacity;\n}\n\n.is-visible {\n transform: translateY(0);\n opacity: 1;\n}Run Code Online (Sandbox Code Playgroud)\r\nload文档的事件您可以将 JS 初始化代码包装到load整个文档的事件中。所有资源(CSS、IMG、..)完全加载后会触发该事件。
window.addEventListener(\'load\', (event) => {\n // JS init code hier (images are loaded at this point!)\n});\nRun Code Online (Sandbox Code Playgroud)\n