我在我的网站上做动画。我正在使用类似版本的jsfiddle代码链接如下。当在桌面上观看动画时,效果很好。然而,当在手机上观看,特别是在我的铬浏览器上,有一个奇怪的滞后。当我在手机上打开它时,弹琴显示出完全相同的滞后。如果我重新启动铬应用程序,延迟就会消失,很快就会回来。
这个问题在Safari中没有发生。
我有最新的iPhone与IOS 14.6和铬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>
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;
}
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))
);
}
我为这个小小的屏幕道歉,我的手机上没有JSfiddle的全屏:
动画在重新启动移动铬后立即工作:https://www.loom.com/share/ac6c843b90d2428bb875572d55e32959
动画中断后不久(当我关闭/重新加载页面):https://www.loom.com/share/e51cf88aa1a74aed8e4d1ed253e83ea0
这正是我在我的网站上看到的使用移动铬浏览器的行为。
更新:下面的答案对我都没有用。我忘了提到这种行为也发生在文本上。此外,谢谢你建议的代码框,我分叉你的代码,并使它更简单,删除图像,但我仍然得到相同的结果,在我的iphone铬浏览器。我还试着用onload函数包装所有东西,但这也不起作用。
目前,我能够用JQuery动画修复这个问题,但我仍然希望CSS3转换能够在我的站点上工作。
https://codesandbox.io/s/animation-test-forked-tqurn?file=/index.html
发布于 2021-07-22 22:20:59
在加载页面时,这看起来像是一个“争用条件”问题。JS在IMG请求完成之前运行。
要理解这个问题,有必要理解加载顺序:
- CSS
- JS
- IMGs
height
,并且新添加的CSS类is-visible
无论如何都会启动transition
.以下是三个可能解决问题的选项:
保留图像的最终尺寸。
height
,并在html中添加类:
.myImg {宽度:50;高度:50;}width
和height
作为html属性。即使*.css仍然在加载,最后的维度在JS中也是可用的。添加一些图像的“负载检测”,防止在图像完全加载之前的过渡。
src
,检测到了height
-onload
事件(因为它尚未加载)src
被设置为data-src
属性,并且一旦图像可用,src
将由JS设置。现在,我们可以使用isLoaded(element)
函数来排除当前未完全加载的.scroll()
中的图像。
这里是jsFiddle,或者展开下面的示例..。
var elementsToShow = document.querySelectorAll('.show-on-scroll');
$(window).scroll(function() {
Array.prototype.forEach.call(elementsToShow, function (element) {
if (isLoaded(element) && isElementInViewport(element)) {
element.classList.add('is-visible');
} else {
element.classList.remove('is-visible');
}
});
});
[...elementsToShow].forEach((imgEl, i) => {
if (
imgEl.src &&
imgEl.getBoundingClientRect().height
) {
imgEl.dataset.isLoaded = true;
console.log(`Img ${i} already loaded`);
} else {
console.log(`Img ${i} still loading... or should be lazyloaded`);
imgEl.onload = function(e) {
console.log(`Img ${i} finally loaded! onload event`);
e.target.dataset.isLoaded = true;
};
if (imgEl.dataset.src) {
console.log(`Img ${i} start lazy load...`);
imgEl.src = imgEl.dataset.src;
}
}
})
function isLoaded(el) {
return el.dataset.isLoaded
}
var elementsToShow = document.querySelectorAll('.show-on-scroll');
$(window).scroll(function() {
Array.prototype.forEach.call(elementsToShow, function(element) {
if (isLoaded(element) && isElementInViewport(element)) {
element.classList.add('is-visible');
} else {
element.classList.remove('is-visible');
}
});
});
[...elementsToShow].forEach((imgEl, i) => {
if (
imgEl.src &&
imgEl.getBoundingClientRect().height
) {
imgEl.dataset.isLoaded = true;
console.log(`Img ${i} already loaded`);
} else {
console.log(`Img ${i} still loading... or should be lazyloaded`);
imgEl.onload = function(e) {
console.log(`Img ${i} finally loaded! onload event`);
e.target.dataset.isLoaded = true;
};
if (imgEl.dataset.src) {
console.log(`Img ${i} start lazy load...`);
imgEl.src = imgEl.dataset.src;
}
}
});
function isLoaded(el) {
return el.dataset.isLoaded
}
// 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))
);
}
.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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<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' />
<img class='balltest show-on-scroll standard-push' data-src='http://www.pngall.com/wp-content/uploads/5/Sports-Ball-Transparent.png' />
<img class='balltest show-on-scroll fade-in' data-src='http://www.pngall.com/wp-content/uploads/5/Sports-Ball-Transparent.png' />
<p style='margin-bottom: 100vh'>below</p>
</html>
C.等待文档的load
事件
可以将JS初始化代码包装到整个文档的load
事件中。事件在所有重新源(CSS、IMG、..)之后触发。全都装好了。
window.addEventListener('load', (event) => {
// JS init code hier (images are loaded at this point!)
});
发布于 2021-07-22 22:41:07
我在Chrome浏览器上测试了您的iPhone代码,无法复制显示在屏幕记录中的错误。
这是否与试图在移动铬浏览器上运行整个jsfiddle web应用程序有关?这是一个笨重的web应用程序,除了你正在测试的任何实际输出之外,还会有很多事情发生在引擎盖下面,所以这可能会导致性能问题。最好只测试输出本身。
我已经将您的代码迁移到了一个代码框中,它将允许您在移动浏览器中单独查看输出(参见下面)。您可以自己判断您所看到的问题是否是一个实际的代码错误。
还应该注意到,您正在使用的球图像是文件大小(~200 be )中的相当大,用于显示它的大小。因此,当它在页面上加载时,看到它闪烁是不寻常的。
下面是球映像的较小版本(缩小了80%,并使用https://tinypng.com/进行了优化),最终大小为42 it (您肯定可以使它更小):
--这里是代码框上的相同代码:
https://codesandbox.io/s/animation-test-ok1dp
这里只有输出(尝试在设备上的移动浏览器中查看此内容):
这里有一个屏幕视频(我用Chrome浏览器在iPhone上捕捉到):
发布于 2021-07-28 04:01:00
我也面对这种情况。在其他浏览器上,它是平滑的。在Chrome手机上,它是如此的滞后。当我将iPhone更新为iOS 14时,就会出现这种情况。
https://stackoverflow.com/questions/68385134
复制相似问题