Я работаю над задачей, в которой каждый раз, когда пользователь прокручивает или изменяет размер экрана, я хотел бы пересчитать свойства css для элемента.
Допустим, я хочу импл. индикатор выполнения, и прогресс отображается в зависимости от положения прокрутки в окне
<div class='progress-bar-wrap'>
<div class='progress-bar-progress'></div>
</div>
function updateScrollProgress () {
this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}
Я попытался подключиться к событиям прокрутки и изменения размера, но это, похоже, дает эффект задержки.
window.on('scroll', updateScrollProgress)
window.on('resize', updateScrollProgress)
Я пробовал в обработчиках событий прокрутки и изменения размера на requestAnimationFrame
window.on('scroll', function(){window.requestAnimationFrame( updateScrollProgress))
window.on('resize', function(){window.requestAnimationFrame( updateScrollProgress))
И испытал огромное улучшение в большинстве браузеров, однако иногда он все же тормозит.
Я пытался запросить другой кадр, когда из обработчика requestAnimationFrame:
function updateScrollProgress () {
window.requestAnimationFrame( updateScrollProgress)
this.progressIndicator.css('width', this.calculateProgressBarWidth() + 'px');
}
Это полностью устранило эффект запаздывания, но привело к затратам на бесконечный цикл вызовов этого метода, даже если не требуется никаких перерасчетов.
Есть ли способ подключить обработчик непосредственно перед тем, как браузер решит нарисовать элемент (ы), чтобы я мог предоставить / установить эти «динамические» значения css для свойства?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Что вы делаете, когда используете requestAnimationFrame. Если вы избавились от задержки с ее помощью, непонятно, почему вы говорите, что функция запускается «слишком часто». Обычно в таком контексте «слишком часто» означает «вызывает отставание» (слишком частое выполнение и замедление работы). Если ваш нет, то ...?
Если вы хотите, чтобы обработчик вызывался реже, вы можете отладить его, но тогда вы, вероятно, заметите задержки перед необходимыми изменениями (потому что вы отреагировали), что, похоже, именно то, чего вы пытаетесь избежать.
В любом случае, requestAnimationFrame, по крайней мере, на данный момент, является правильным инструментом для работы «непосредственно перед тем, как браузер отобразит фрейм».
Хорошо, я предоставлю пример кода. Дело в том, что я хотел бы каким-то образом предоставить другое значение css непосредственно перед тем, как браузер решит выполнить рендеринг. Скажем, я хотел бы, чтобы высота была функцией положения прокрутки документа, например.
@Nas - вот что такое requestAnimationFrame: обратный вызов непосредственно перед отображением кадра браузером.
А когда зацепить ?? И выполнять только тогда, когда есть перекомпоновка элементов
@Nas - всякий раз, когда вам нужно внести изменения. Итак, если все это основано на прокрутке, я бы перехватил событие прокрутки, выполнил бы расчет, и если значение отличается от последнего значения, которое я использовал, я бы запланировал обратный вызов rAF, чтобы использовать это новое значение, и помню, я использовал это. Если для вас это слишком медленно, то ждать события прокрутки, по-видимому, уже слишком поздно. Если это так, просто всегда находиться в цикле rAF (подключать его к нагрузке и каждый раз повторно) - это то, что вам нужно сделать. Делайте вычисления как можно короче, но в среднем каждые 16,6 мс, когда ваша функция, вероятно, выполняется в микросхемах.
Спасибо - к сожалению, бесконечный цикл обратных вызовов rAF дает лучшие результаты на данный момент .. Мне было интересно, смогу ли я подключить его прямо перед тем, как браузеру потребуется перерисовать и элемент в качестве альтернативы бесконечному циклу ..
@Nas - Опять же, это то, что вы делаете, когда вызываете rAF (но только на уровне всей страницы, я думаю, я могу понять, что вы имеете в виду, говоря о обратном вызове для конкретного элемента). Похоже, что по какой-то причине событие scroll происходит слишком поздно для вас, следовательно, scroll + rAF не подходит. Ведется некоторая работа над точками расширения в, рендерингом, но это как минимум через пару лет. Хотел бы я найти страницу, на которой я читал об этом, чтобы показать вам ...
Что ж, я заметил, что когда я задаю параметры с бесконечным циклом и веду журнал консоли, код постоянно выполняется. Поэтому я хочу не всегда запрашивать другой кадр, а всякий раз, когда по какой-то причине запускается новое переформатирование - когда что-то вызывает перерисовку, чтобы перехватить мой код ...
Поэтому я не хочу запрашивать кадр анимации. Я хочу, чтобы кадр анимации запрашивал меня: P
@Nas :-) Я считаю, что это именно тот крючок, о котором идет речь. Драт, я бы хотел найти эту страницу ...
Надеюсь, это пройдет. К сожалению, мне не удалось найти такой / похожий крючок для выполнения работы на данный момент. Но спасибо, что попробовали со мной :)
@Nas - Нашел это: drafts.css-houdini.org/worklets У меня еще не было возможности прочитать его, поэтому он может не иметь отношения к вашей проблеме, но ...
Оберните вашу функцию события через функцию противодействия:
Более подробная информация о функциях отладки здесь:
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);
Спасибо, но я хочу убрать эффект запаздывания, к сожалению, его устранение будет иметь противоположный эффект :(
задержка обычно вызвана тем, что обработчик событий вызывается несколько раз в секунду, поэтому устранение неполадок обычно исправляет это, по крайней мере, для меня.
Спасибо, но в данном случае задержка вызвана поздним вызовом обработчика. К сожалению, устранение неполадок сделает вызов еще более поздним и, следовательно, продлит задержку :(
Если вы избавились от задержки, почему обработчик вызывается «слишком часто»? Обычно «слишком часто» в этом контексте означает «вызывает отставание» (слишком частое выполнение и, таким образом, замедление работы).