简体   繁体   English

如何提供动态(计算的)css属性

[英]How to provide a dynamic (calculated) css property

I am working on task in which each time a user scrolls or resizes the screen I would like to recalculate a css properties for an element. 我正在执行一项任务,其中每当用户滚动或调整屏幕大小时,我都希望重新计算元素的CSS属性。

Let's say I want to impl. 假设我想暗示。 a progress bar and the progress is reported based on the scroll position in the window 进度条,并根据窗口中的滚动位置报告进度

<div class='progress-bar-wrap'>
   <div class='progress-bar-progress'></div>
</div>

function updateScrollProgress () {
   this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}

I tried to hook on scroll and resize events, but this seem to have a laggy effect. 我试图抓住滚动和调整事件的大小,但这似乎效果不佳。

window.on('scroll', updateScrollProgress)
window.on('resize', updateScrollProgress)

I tried in the scroll and resize event handlers to requestAnimationFrame 我在滚动和尝试调整事件处理程序的大小以尝试requestAnimationFrame

window.on('scroll', function(){window.requestAnimationFrame( updateScrollProgress))
window.on('resize', function(){window.requestAnimationFrame( updateScrollProgress))

And experienced huge improvement in most browsers, however it is yet occasionally laggy. 在大多数浏览器中都经历了巨大的改进,但是偶尔还是有些落后。

I tried to request another frame, when from the requestAnimationFrame handler: 我尝试从requestAnimationFrame处理程序请求另一个框架:

function updateScrollProgress () {
   window.requestAnimationFrame( updateScrollProgress)
   this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}

This completely eliminated the laggy effect, but comes to the cost of endless loop of calls to this method, even when no recalculations are needed. 这完全消除了滞后效应,但是,即使不需要重新计算,也要无休止地调用此方法。

Is there a way to hook a handler just before the browser decides to draw element(s), so that I can provide/set the those "dynamic" css values for a property? 有没有一种方法可以在浏览器决定绘制元素之前挂接处理程序,以便为属性提供/设置那些“动态” css值?

What's what you're doing when you use requestAnimationFrame . 当您使用requestAnimationFrame时,您正在做什么。 If you've gotten rid of the lag using it, it's unclear why you say the function is running "too often." 如果您已经摆脱了使用它的滞后,则不清楚您为什么说该函数“经常运行”。 Usually in this sort of context, "too often" means "is causing lag" (by running too often and slowing things down). 通常,在这种情况下,“太频繁”的意思是“造成延迟”(通过频繁运行和放慢速度)。 If yours isn't, then...? 如果不是,那...?

If you want the handler called less often, you can debounce it, but then you'll probably notice delays before the changes you want (because you've debounced), which it sounds like is what you're trying to avoid. 如果您希望处理程序的调用频率降低,则可以对其进行反跳,但是您可能会注意到想要的更改之前有所延迟(因为已被反跳),这听起来像是您要避免的事情。

In any case, requestAnimationFrame is, for now at least, the right tool for the "just before the browser renders the frame" job. 无论如何,至少到目前为止, requestAnimationFrame是“就在浏览器呈现框架之前”作业的正确工具。

Wrap your event function through a debounce function: 通过去抖功能包装事件功能:

More info on debounce functions here: 有关反跳功能的更多信息,请参见:

https://davidwalsh.name/javascript-debounce-function https://davidwalsh.name/javascript-debounce-function

function debounce(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

var myEfficientFn = debounce(function() {
  // All the taxing stuff you do
}, 250);

window.addEventListener('resize', myEfficientFn);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM