javascript - 滚动混合效果 - 除 Chrome 之外的所有浏览器中的性能问题

标签 javascript html css

借助在 previous answer 中收到的帮助,我利用一些 JS 和 CSS 变量在滚动页面时实现“混合”效果,如 this working example 中所示。 .

这个解决方案很棒……但仅限于 Chrome。不过,我已经开始在我的元素中实现这一点,并且在其他浏览器中进行的测试揭示了严重的性能问题,特别是内容 block 在滚动时跳来跳去。我在 Firefox 和 Safari 中重新访问了我的测试示例,发现了同样的问题。

所以我的问题很简单,我可以做些什么来提高这个效果的性能?我已经做了很多搜索以找到一种替代方法来实现这种效果,但到目前为止还没有运气。不过,也许我可以对我的 JS 进行修改以解决这些问题。

我在下面包含了我的代码以供引用。任何帮助将不胜感激。

window.onscroll = function() {
  var scroll = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
  document.documentElement.style.setProperty('--scroll-var', scroll + "px");
}
:root {
  --scroll-var: 0px
}

body {
  margin: 0;
  padding: 0;
}

h2 {
  font-size: 48px;
}

p {
  font-size: 18px;
}

section {
  min-height: 100vh;
  width: 100%;
  text-align: center;
  overflow: hidden;
  background-attachment: fixed !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  position: relative; /*Mandatory for the overflow effect*/
  height: 100vh;
}

section.first {
  background: linear-gradient(rgba(74, 180, 220, .85), rgba(74, 180, 220, .85)), url(https://picsum.photos/1920/500/?image=1057);
}

section.first .content {
  /* the first section so top start from 0*/
  top: calc((0 * 100vh) + var(--scroll-var));
}

section.second {
  background: linear-gradient(rgba(103, 198, 180, .85), rgba(103, 198, 180, .85)), url(https://picsum.photos/1920/500/?image=1067);
}

section.second .content {
  /* the second section so we need to remove the height of top section
     to have the same position so -100vh and we do the same for the other sections  
  */
  top: calc((-1 * 100vh) + var(--scroll-var));
}

section.third {
  background: linear-gradient(rgba(5, 123, 188, .85), rgba(5, 123, 188, .85)), url(https://picsum.photos/1920/500/?image=1033);
}

section.third .content {
  top: calc((-2 * 100vh) + var(--scroll-var));
}

section.fourth {
  background: linear-gradient(rgba(187, 216, 100, .85), rgba(187, 216, 100, .85)), url(https://picsum.photos/1920/500?image=1063);
}

section.fourth .content {
  top: calc((-3 * 100vh) + var(--scroll-var));
}

.content {
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.copy {
  color: #fff;
  font-family: 'Noto Serif', serif;
  font-weight: 300;
  max-width: 300px;
}

.button {
  border: 2px solid #fff;
  border-radius: 3px;
  padding: 15px 25px;
  display: inline-block;
  width: auto;
  font-family: 'Assistant', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: .2s ease all;
}

.button:hover {
  background: #fff;
  color: #333;
  cursor: pointer;
}
<body>
  <section class="first">
    <div class="content">
      <div class="copy">
        <h2>Header 1 </h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="second">
    <div class="content">
      <div class="copy">
        <h2>Header 2</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="third">
    <div class="content">
      <div class="copy">
        <h2>Header 3</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="fourth">
    <div class="content">
      <div class="copy">
        <h2>Call to action</h2>
        <a class="button">Button</a>
      </div>
    </div>
  </section>
</body>

最佳答案

我认为通过简化计算最高值的逻辑可以解决您的问题。您可以为每个部分使用固定的顶部值,然后为所有部分调整 margin-top

你也可以去掉 CSS 变量:

var all = document.querySelectorAll('.content');
var l = all.length;

window.onscroll = function() {
  var scroll = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
  for(var i=0;i<l;i++)
   all[i].style.marginTop=scroll + "px";
}
body {
  margin: 0;
  padding: 0;
}

h2 {
  font-size: 48px;
}

p {
  font-size: 18px;
}

section {
  min-height: 100vh;
  width: 100%;
  text-align: center;
  overflow: hidden;
  background-attachment: fixed !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  position: relative; /*Mandatory for the overflow effect*/
  height: 100vh;
}

section.first {
  background: linear-gradient(rgba(74, 180, 220, .85), rgba(74, 180, 220, .85)), url(https://picsum.photos/1920/500/?image=1057);
}

section.first .content {
  /* the first section so top start from 0*/
  top:0;
}

section.second {
  background: linear-gradient(rgba(103, 198, 180, .85), rgba(103, 198, 180, .85)), url(https://picsum.photos/1920/500/?image=1067);
}

section.second .content {
  /* the second section so we need to remove the height of top section
     to have the same position so -100vh and we do the same for the other sections  
  */
  top: -100vh;
}

section.third {
  background: linear-gradient(rgba(5, 123, 188, .85), rgba(5, 123, 188, .85)), url(https://picsum.photos/1920/500/?image=1033);
}

section.third .content {
  top: -200vh;
}

section.fourth {
  background: linear-gradient(rgba(187, 216, 100, .85), rgba(187, 216, 100, .85)), url(https://picsum.photos/1920/500?image=1063);
}

section.fourth .content {
  top:-300vh;
}

.content {
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top:0px;
}

.copy {
  color: #fff;
  font-family: 'Noto Serif', serif;
  font-weight: 300;
  max-width: 300px;
}

.button {
  border: 2px solid #fff;
  border-radius: 3px;
  padding: 15px 25px;
  display: inline-block;
  width: auto;
  font-family: 'Assistant', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: .2s ease all;
}

.button:hover {
  background: #fff;
  color: #333;
  cursor: pointer;
}
<body>
  <section class="first">
    <div class="content">
      <div class="copy">
        <h2>Header 1 </h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="second">
    <div class="content">
      <div class="copy">
        <h2>Header 2</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="third">
    <div class="content">
      <div class="copy">
        <h2>Header 3</h2>
        <p>Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</p>
      </div>
    </div>
  </section>
  <section class="fourth">
    <div class="content">
      <div class="copy">
        <h2>Call to action</h2>
        <a class="button">Button</a>
      </div>
    </div>
  </section>
</body>

关于javascript - 滚动混合效果 - 除 Chrome 之外的所有浏览器中的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50671354/

相关文章:

javascript - 选项在 Materialize 中不起作用,当我使用 jQuery 附加方法时,删除方法也不起作用

javascript - 如何使用 scrollTop 反转动画

javascript - Jquery提交表单而不刷新

jquery - 媒体查询和 JQuery 问题

具有许多嵌套和 float Div 的 CSS 100% 高度

javascript - 如何将 React 元素转换为 dom 元素

javascript - 图表 : Many different series at the same chart impact Legend display very badly

javascript - HTML 中是否允许 <head> 和 <body> 之外的 &lt;script&gt; 标记?

html - 选中单选按钮时更改标签和图像不透明度?

html - 移动设备未读取媒体查询