Javascript “此站点似乎使用滚动链接定位效果。这可能不适用于异步平移”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37098306/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:54:48  来源:igfitidea点击:

"This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning"

javascriptjqueryfirefox

提问by Michael Hancock

I have been given this unusual warning from Firefox. The positioning effect it refers to is a divI rotate as a factor of the scroll height. I have never had any problems with it, but is this something I should be concerned about? Is there anyway to have such effects without this warning? The JavaScript that demonstrates this issue is:

我收到了来自 Firefox 的这个不寻常的警告。它所指的定位效果是一个divI 旋转作为滚动高度的一个因素。我从来没有遇到过任何问题,但这是我应该担心的事情吗?无论如何,如果没有这个警告,会有这样的影响吗?演示此问题的 JavaScript 是:

//Rotate gears in about section
$('.gear').css({
   'transition': 'transform 1s ease-out',
   '-webkit-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   '-moz-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   '-ms-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   'transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
});
  • wScrollis the current scroll height
  • wScroll是当前滚动高度

采纳答案by Nickolay

The warning, I think, goes on to say:

我认为,警告继续说:

...see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffectsfor further details and to join the discussion on related tools and features!

...请参阅https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects了解更多详情并加入相关工具和功能的讨论!

But in case that page is unclear, here's the gist of it.

但如果该页面不清楚,这里是它的要点。

The idea of "asynchronous panning" is this: when the page is scrolled, the browser calls your scrollhandler, but it also asynchronouslypaints the page at the new scroll-point. This is done to make scrolling appear responsive (@ 60 FPS) even when the main thread is busy for more than 16ms.

“异步平移”的想法是这样的:当页面滚动时,浏览器调用您的scroll处理程序,但它也会在新的滚动点异步绘制页面。这样做是为了使滚动显示响应(@ 60 FPS),即使主线程繁忙超过 16 毫秒。

This means that the effects your handler implements are not guaranteed to be in sync with the current scrolling position. I.e. the scrolling is smooth, but your divs rotate with a smaller FPS -- appearing janky, non-smooth.Update, missed the transitioneffect in your example -- the rotation itself will also be smooth, but it might start later than the page starts to scroll.

这意味着您的处理程序实现的效果不能保证与当前滚动位置同步。即滚动是平滑的,但是您的 div 以较小的 FPS 旋转 - 出现卡顿、不流畅。更新transition在您的示例中错过了效果——旋转本身也将是平滑的,但它可能会晚于页面开始滚动。

I don't think you can implement the exact effect you have with the currently available technologies without having this problem.

我不认为你可以在没有这个问题的情况下实现你使用当前可用技术的确切效果。

example

例子

(Note that to see the APZin action, you need to be running the Firefox version with it enabled. In particular this requires Firefox to be running in a multiprocess ("e10s") mode, which is still not in the release builds at this time.)

(请注意,要查看APZ 的运行情况,您需要在启用它的情况下运行 Firefox 版本。特别是这需要 Firefox 以多进程(“e10s”)模式运行,该模式目前仍未在发布版本中时间。)

window.onscroll = function() {
  var wScroll = document.documentElement.scrollTop;
  document.getElementById("gear-css").style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js") .style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js").textContent = leftPad(wScroll+'', '0', 4);

  setTimeout(slowdown(500), 0);
};

function leftPad(s, ch, maxLen) { return ch.repeat(maxLen - s.length) + s; }
function slowdown(timeMs) {
  return function() {
    var start = Date.now();
    var j = "";
    for (var i = 0; (Date.now() - start < timeMs); i++)
      j = j+(start+"")*i;
  }
}


window.onload = function() {
  for (let i = 0; i < 15; i++) {
    var p = document.createElement("p");
    p.innerText = `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
          tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
          quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
          consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
          cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
          proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
    document.documentElement.appendChild(p);
  }
}
#gear-css, #gear-js {
  border: solid black 1px;
}
#gear-css {
  transition: transform 1s ease-out
}
<div style="position: fixed; top: 0; right: 0; padding: 3em;">
  <div id="gear-css">ooo</div>
  <div id="gear-js">ooo</div>
</div>

回答by QWERTYUIOPYOZO

I know that this question was asked some time ago, however, the performance issue still exists. Below is an alternative solution that does not rely upon a scrolling event listener. This minimises jank and lag caused by the separate scrolling thread common among web browsers, updating the css at regular intervals rather than when the window is scrolled. This means that the dev console warning will not display. I personally wouldn't be too worried about the warning or using scrolling events for small things like turning a gear or changing a css class, however, if the user experience directly relies upon the effect, it will destroy the usability of the page.

我知道这个问题是前一段时间被问到的,但是,性能问题仍然存在。以下是不依赖滚动事件侦听器的替代解决方案。这最大限度地减少了由 Web 浏览器中常见的单独滚动线程引起的卡顿和延迟,定期更新 css,而不是在滚动窗口时。这意味着不会显示开发控制台警告。我个人不会太担心警告或使用滚动事件来处理诸如转动齿轮或更改css类之类的小事情,但是,如果用户体验直接依赖于效果,则会破坏页面的可用性。

var gear;
var lastPosition;
var refreshRate = 60; // fps; reduce for less overhead
var animation = "rotate(*deg)"; // css style to apply [Wildcard is *]
var link = 0.5; //what to multiply the scrollTop by

function replace(){
    if(lastPosition != document.body.scrollTop){ // Prevents unnecessary recursion
        lastPosition = document.body.scrollTop; // updates the last position to current
        gear.style.transform = animation.replace("*", Math.round(lastPosition * link)); // applies new style to the gear
    }
}

function setup(){
    lastPosition = document.body.scrollTop;
    gear = document.querySelector(".gear");
    setInterval(replace, 1000 / refreshRate); // 1000 / 60 = 16.666... Invokes function "replace" to update for each frame
}
window.addEventListener("DOMContentLoaded", setup);

A working example can be used on my GitHub. I have tested it on Firefox, Chrome and Edge (works).

可以在我的 GitHub 上使用一个工作示例。我已经在 Firefox、Chrome 和 Edge(有效)上对其进行了测试。

Other alternatives to avoiding the warning are to use css sticky elementsor use the element.classList.add()and element.classList.remove()methods limnked to a window.onscrollevent.

避免警告的其他替代方法是使用css 粘性元素或使用与window.onscroll事件相关联的element.classList.add()element.classList.remove()方法。

Note:Be careful about using css transitions where the length of the transition is longer than the interval at which the CSS style will be updated by the script (such as with scrolling event based changes). Webkit based browsers and EdgeHTML will behave in unexpected ways to this, usually staying in their initial position until the element stops being updated by the script. Unless this is the effect you were intending, in which case it doesn't work the same way in firefox.

注意:在使用 css 过渡时要小心,如果过渡的长度大于脚本更新 CSS 样式的间隔(例如基于滚动事件的更改)。基于 Webkit 的浏览器和 EdgeHTML 会以意想不到的方式运行,通常保持在它们的初始位置,直到元素停止被脚本更新。除非这是您想要的效果,在这种情况下,它在 Firefox 中的工作方式不同。

Servo Webrender, when integrated into Firefox will solve these problems to an extent (or at least improve the performance quite considerably). Although there will still be other browsers to maintain compatibility with.

Servo Webrender 集成到 Firefox 后将在一定程度上解决这些问题(或者至少可以相当大地提高性能)。虽然仍然会有其他浏览器来保持兼容性。

回答by Constantin

the best solution is a switch and a timer i expose here the answer to solve the same error when you use "on scroll" , i suggest you to adapt my script to your needs! https://stackoverflow.com/a/57641938/5781320

最好的解决方案是一个开关和一个计时器,我在这里公开了解决相同错误的答案,当您使用“滚动”时,我建议您根据自己的需要调整我的脚本! https://stackoverflow.com/a/57641938/5781320