Как предоставить динамическое (вычисляемое) свойство css

Я работаю над задачей, в которой каждый раз, когда пользователь прокручивает или изменяет размер экрана, я хотел бы пересчитать свойства 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 для свойства?

Если вы избавились от задержки, почему обработчик вызывается «слишком часто»? Обычно «слишком часто» в этом контексте означает «вызывает отставание» (слишком частое выполнение и, таким образом, замедление работы).

T.J. Crowder 07.11.2018 14:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
61
2

Ответы 2

Что вы делаете, когда используете requestAnimationFrame. Если вы избавились от задержки с ее помощью, непонятно, почему вы говорите, что функция запускается «слишком часто». Обычно в таком контексте «слишком часто» означает «вызывает отставание» (слишком частое выполнение и замедление работы). Если ваш нет, то ...?

Если вы хотите, чтобы обработчик вызывался реже, вы можете отладить его, но тогда вы, вероятно, заметите задержки перед необходимыми изменениями (потому что вы отреагировали), что, похоже, именно то, чего вы пытаетесь избежать.

В любом случае, requestAnimationFrame, по крайней мере, на данный момент, является правильным инструментом для работы «непосредственно перед тем, как браузер отобразит фрейм».

Хорошо, я предоставлю пример кода. Дело в том, что я хотел бы каким-то образом предоставить другое значение css непосредственно перед тем, как браузер решит выполнить рендеринг. Скажем, я хотел бы, чтобы высота была функцией положения прокрутки документа, например.

Nas 07.11.2018 13:58

@Nas - вот что такое requestAnimationFrame: обратный вызов непосредственно перед отображением кадра браузером.

T.J. Crowder 07.11.2018 14:01

А когда зацепить ?? И выполнять только тогда, когда есть перекомпоновка элементов

Nas 07.11.2018 14:06

@Nas - всякий раз, когда вам нужно внести изменения. Итак, если все это основано на прокрутке, я бы перехватил событие прокрутки, выполнил бы расчет, и если значение отличается от последнего значения, которое я использовал, я бы запланировал обратный вызов rAF, чтобы использовать это новое значение, и помню, я использовал это. Если для вас это слишком медленно, то ждать события прокрутки, по-видимому, уже слишком поздно. Если это так, просто всегда находиться в цикле rAF (подключать его к нагрузке и каждый раз повторно) - это то, что вам нужно сделать. Делайте вычисления как можно короче, но в среднем каждые 16,6 мс, когда ваша функция, вероятно, выполняется в микросхемах.

T.J. Crowder 07.11.2018 14:11

Спасибо - к сожалению, бесконечный цикл обратных вызовов rAF дает лучшие результаты на данный момент .. Мне было интересно, смогу ли я подключить его прямо перед тем, как браузеру потребуется перерисовать и элемент в качестве альтернативы бесконечному циклу ..

Nas 07.11.2018 14:19

@Nas - Опять же, это то, что вы делаете, когда вызываете rAF (но только на уровне всей страницы, я думаю, я могу понять, что вы имеете в виду, говоря о обратном вызове для конкретного элемента). Похоже, что по какой-то причине событие scroll происходит слишком поздно для вас, следовательно, scroll + rAF не подходит. Ведется некоторая работа над точками расширения в, рендерингом, но это как минимум через пару лет. Хотел бы я найти страницу, на которой я читал об этом, чтобы показать вам ...

T.J. Crowder 07.11.2018 14:27

Что ж, я заметил, что когда я задаю параметры с бесконечным циклом и веду журнал консоли, код постоянно выполняется. Поэтому я хочу не всегда запрашивать другой кадр, а всякий раз, когда по какой-то причине запускается новое переформатирование - когда что-то вызывает перерисовку, чтобы перехватить мой код ...

Nas 07.11.2018 14:32

Поэтому я не хочу запрашивать кадр анимации. Я хочу, чтобы кадр анимации запрашивал меня: P

Nas 07.11.2018 14:35

@Nas :-) Я считаю, что это именно тот крючок, о котором идет речь. Драт, я бы хотел найти эту страницу ...

T.J. Crowder 07.11.2018 14:38

Надеюсь, это пройдет. К сожалению, мне не удалось найти такой / похожий крючок для выполнения работы на данный момент. Но спасибо, что попробовали со мной :)

Nas 07.11.2018 17:22

@Nas - Нашел это: drafts.css-houdini.org/worklets У меня еще не было возможности прочитать его, поэтому он может не иметь отношения к вашей проблеме, но ...

T.J. Crowder 07.11.2018 17:36

Оберните вашу функцию события через функцию противодействия:

Более подробная информация о функциях отладки здесь:

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);

Спасибо, но я хочу убрать эффект запаздывания, к сожалению, его устранение будет иметь противоположный эффект :(

Nas 07.11.2018 14:00

задержка обычно вызвана тем, что обработчик событий вызывается несколько раз в секунду, поэтому устранение неполадок обычно исправляет это, по крайней мере, для меня.

dotconnor 07.11.2018 14:08

Спасибо, но в данном случае задержка вызвана поздним вызовом обработчика. К сожалению, устранение неполадок сделает вызов еще более поздним и, следовательно, продлит задержку :(

Nas 07.11.2018 17:21

Другие вопросы по теме