如何修复Chrome中的页面滚动滞后

时间:2019-01-18 09:17:38

标签: jquery css google-chrome

我一直在一个新的静态网站上工作,这是一个非常简单的构建,但是有一些由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

3 个答案:

答案 0 :(得分:1)

在此示例中,我有太多担忧;

  • 摆脱Jquery的速度很慢,您可以使用JS(http://youmightnotneedjquery.com/)来做所有事情
  • 为什么超时?不用了如果要使用它,请杀死其他超时,这样就不会重复。
  • 使用ES6(易于理解,阅读和编​​码),您也可以编译到较低版本。它可以让您随时更新自己的职业道路。
  • 不要为每个滚动运行选择器。滚动前使用选择器。

这里是示例:

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支持较旧的浏览器。