当元素位于视口中时开始视差

Ant*_*nja 0 javascript

我在一个对多个元素(文本、图像等)具有视差效果的网站上工作。当元素位于视口底部时,我需要启动视差效果。

在这种情况下,元素距离页面顶部 3000px,当元素位于视口中时,我想将 window.pageYOffset 重置为零(或类似的值),这样效果才有意义。

这段代码可以工作,但效果不好,当我更改分隔符高度时,视差效果的开始位置不同。您可以尝试将 css 中的分隔符高度更改为 500px 和 5000px。

对此有什么更好的解决方案?

谢谢

这是小提琴: https: //jsfiddle.net/you8c6d7/

function parallax(element, delay) {
  var start = document.querySelector(element).getBoundingClientRect().top;
  var px = window.pageYOffset - (start * 2 + window.innerHeight);
  var elClass = document.querySelector(element);

  elClass.style.transform = 'translateY(' + '-' + px / delay + 'px' + ')';
};

window.addEventListener('scroll', function() {
  parallax('.box', 5);
});
Run Code Online (Sandbox Code Playgroud)
body {
  height: 6000px;
  margin 0;
}

.box {
  background: blue;
  width: 300px;
  height: 300px;
}

.separator {
  height: 500px;
  background: grey;
}
Run Code Online (Sandbox Code Playgroud)
<div class="separator"></div>
<div class="box"></div>
Run Code Online (Sandbox Code Playgroud)

Bar*_*thy 5

这是使用Intersection Observer API 的片段。

\n\n

我使用了实验性功能“IntersectionObserver.thresholds”,因此IE 不支持该功能。

\n\n

根据您的目标受众,您可能需要使用polyfill

\n\n

该脚本观察目标框是否与视口相交,并根据框/视口的比率对其进行变换。有关更多详细信息,请参阅代码内的注释和 JSDoc。

\n\n

\r\n
\r\n
/**\r\n * Creates an IntersectionObserver and starts observing all elements found using the selector.\r\n *\r\n * @param {String} selector: Selector used to find all target elements\r\n * @param {Number[]} threshold: Array of intersection ratios, at which the callback is executed\r\n * @param {Function} callback: Callback executed for each threshold\r\n */\r\nfunction observe(selector, threshold, callback) {\r\n  const elements = document.querySelectorAll(selector);\r\n  const options = {\r\n    rootMargin: \'0px\',\r\n    threshold: threshold,\r\n  };\r\n\r\n  const observer = new IntersectionObserver(callback, options);\r\n\r\n  for (const element of elements) {\r\n    observer.observe(element);\r\n  }\r\n}\r\n\r\n/**\r\n * Creates a CSS translateY value.\r\n *\r\n * @param {Number} ratio: A number between 0 and 1\r\n * @param {String} total: A valid CSS number and unit (10px, 100%, 30vh, \xe2\x80\xa6)\r\n * @return {String} The CSS translateY value.\r\n */\r\nfunction translateY(ratio, total) {\r\n  return `translateY(calc(-${ratio} * ${total})`;\r\n}\r\n\r\n/**\r\n * Callback executed for the box elements\r\n *\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\r\n *\r\n * @param {IntersectionObserverEntry[]} entries: Intersection Observer Entries\r\n * @param {IntersectionObserver} observer: Intersection Observer\r\n */\r\nfunction boxParallax(entries, observer) {\r\n  for (const entry of entries) {\r\n    if (entry.isIntersecting) {\r\n      entry.target.style.transform = translateY(entry.intersectionRatio, \'20%\');\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * Create one threshold for each intersection ratio.\r\n *\r\n * @return {Number[]}\r\n */\r\nfunction createThreshold() {\r\n  const threshold = [];\r\n  for (let i = 0; i <= 1.0; i += 0.01) {\r\n    threshold.push(i);\r\n  }\r\n\r\n  return threshold;\r\n}\r\n\r\nconst threshold = createThreshold();\r\nobserve(\'.box\', threshold, boxParallax);
Run Code Online (Sandbox Code Playgroud)\r\n
body {\r\n  height: 6000px;\r\n  margin 0;\r\n}\r\n\r\n.box {\r\n  background: blue;\r\n  width: 300px;\r\n  height: 300px;\r\n}\r\n\r\n.separator {\r\n  height: 500px;\r\n  background: grey;\r\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="separator"></div>\r\n<div class="box"></div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n