我一直在一个新的静态网站上工作,这是一个非常简单的构建,但是有一些由isInViewport
js函数触发的微妙的CSS动画。
我注意到,Chrome呈现页面时滚动时有少量滞后,这非常刺耳。但是,在Safari中,Firefox绝对可以。
这是我的js
,用于在元素处于视口中时触发。
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height() - 100;
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(window).on('resize scroll', function() {
setTimeout(function(){
$('section').each(function() {
if ($(this).isInViewport()) {
$(this).addClass('reveal');
}
else {
}
});
}, 300);
});
我有什么不应该做的事吗?
这是与动画相关的CSS
。
.image-reveal {
position: relative;
overflow: hidden;
}
.image-reveal-cover {
background: #fcfcfc;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 5;
transform: translateX(0);
-webkit-transform: translateX(0);
transition: transform cubic-bezier(.19, 1, .22, 1) 1.75s;
-webkit-transition: transform cubic-bezier(.19, 1, .22, 1) 1.75s;
}
.image-reveal img {
position: relative;
z-index: 2;
opacity: 0;
transform: scale(1.4);
-webkit-transform: scale(1.4);
transition: all cubic-bezier(.19, 1, .22, 1) 1.5s;
-webkit-transition: all cubic-bezier(.19, 1, .22, 1) 1.5s;
}
section.reveal .image-reveal-cover {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
section.reveal .image-reveal img {
opacity: 1;
transform: scale(1);
-webkit-transform: scale(1);
}
这是codepen,显示了Chrome中滚动抖动的示例。
我错误地触发了动画吗?我以为CSS运动的基础使用transform相对没有滞后性?
任何建议都值得赞赏。谢谢。
我也在Chrome 71.0.3578.98
上使用Mac OS Mojave
答案 0 :(得分:1)
在此示例中,我有太多担忧;
这里是示例:
class ScrollControl {
constructor() {
this.sectionDOMList = document.querySelectorAll('section');
this.initListeners();
}
initListeners() {
window.addEventListener('scroll', (e) => {
this.animateSections();
});
}
animateSections() {
for (let i = 0; i < this.sectionDOMList.length; i++) {
if (this.isInViewport(this.sectionDOMList[i])) {
if(!this.sectionDOMList[i].isReveal){
this.sectionDOMList[i].isReveal = true;
this.sectionDOMList[i].classList.add('reveal');
}
}
}
}
isInViewport(element) {
const elementCenter = (element.getBoundingClientRect().top + element.getBoundingClientRect().bottom)/2;
const viewportTop = window.scrollY;
const viewportBottom = viewportTop + window.innerHeight;
return elementCenter < viewportBottom;
}
}
(function() {
new ScrollControl();
})();
/* Reset */
html {
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-size: 16px;
}
*,
*:before,
*:after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
ol,
ul {
margin: 0;
padding: 0;
font-weight: normal;
}
ol,
ul {
list-style: none;
}
img {
max-width: 100%;
height: auto;
}
/* Base */
body {
width: 100%;
height: 100%;
background: white;
color: #3b3b3b;
font-family: 'Larsseit', Helvetica, Arial, sans-serif;
}
.container {
max-width: 1640px;
margin-left: 30px;
margin-right: 30px;
}
@media (min-width: 768px) {
.container {
margin-left: 80px;
margin-right: 80px;
}
}
@media (min-width: 1800px) {
.container {
margin: 0 auto;
}
}
.vc {
display: table;
height: 100%;
}
.vc-ele {
display: table-cell;
vertical-align: middle;
}
section {
padding: 400px 0;
}
section.full-vh {
position: relative;
width: 100%;
height: 100vh;
padding: 0;
}
.row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.col-half {
width: 100%;
}
@media (min-width: 992px) {
.col-half {
width: 50%;
}
}
.row.align-center {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
/* Typography */
h1 {
font-size: 52px;
}
h2 {
font-size: 26px;
}
p {
font-family: 'Larsseit', Helvetica, Arial, sans-serif;
font-size: 16px;
font-weight: 300;
line-height: 1.5;
color: #3b3b3b;
}
/* Image reveal */
.image-reveal {
position: relative;
overflow: hidden;
}
.image-reveal-cover {
background: #fcfcfc;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 5;
transform: translateX(0);
-webkit-transform: translateX(0);
transition: transform cubic-bezier(.19, 1, .22, 1) 1.75s;
-webkit-transition: transform cubic-bezier(.19, 1, .22, 1) 1.75s;
}
.image-reveal img {
position: relative;
z-index: 2;
opacity: 0;
transform: scale(1.4);
-webkit-transform: scale(1.4);
transition: all cubic-bezier(.19, 1, .22, 1) 1.5s;
-webkit-transition: all cubic-bezier(.19, 1, .22, 1) 1.5s;
}
section.reveal .image-reveal-cover {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
section.reveal .image-reveal img {
opacity: 1;
transform: scale(1);
-webkit-transform: scale(1);
}
<div id="page">
<div class="container">
<section class="full-vh">
<div class="vc">
<div class="vc-ele">
<h1>Scroll down</h1>
</div>
</div>
</section>
<section>
<div class="row align-center">
<div class="col-half">
<div class="image-reveal">
<div class="image-reveal-cover"></div>
<img src="https://fearthewild.com/clients/playground/horse.jpg" alt="Horse" />
</div>
</div>
<div class="col-half">
<h2>This is my horse.</h2>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem
quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<p>Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem
ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
</div>
</div>
</section>
</div>
</div>
答案 1 :(得分:1)
Chrome 滚动效果行为的延迟可能是由 CSS 引起的。如果您的 html 或 body 元素上有滚动行为规则,请尝试删除滚动行为规则。
删除这一行:
scroll-behavior: smooth
答案 2 :(得分:0)
不要听滚动(或调整大小)事件,然后计算元素是否在视口中,而应使用Intersection Observer (IO)。
IO观察者一个(或多个)元素,如果它们彼此相交或与视口相交,则会做出反应。
首先,您必须为IO指定选项:
let options = {
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);
在您的情况下,您需要测试与窗口的相交,因此无需为选项指定root
值。我们还指定了每当触发IO时就会执行名为callback的函数。
下一步是定义应遵守的元素,在您的情况下,这些将是section元素:
let targets = document.querySelectorAll('section');
targets.forEach(target => {
observer.observe(target);
});
现在已完成所有设置,剩下要做的就是定义回调函数中实际发生的事情:
let callback = (entries, observer) => {
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element
// I think you are be interested in entry.isIntersecting check.
});
};
还check this example介绍如何根据视口中的可见框来更改背景颜色。
您也可以使用此polyfill from w3c支持较旧的浏览器。