WedX - журнал о программировании и компьютерных науках

Как принудительно перекомпоновать javascript в webkit 1.2.5

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

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

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

Я использую webkit 1.2.5, если это поможет.

Если я не достаточно понимаю, я попытаюсь объяснить лучше.

Это код, который я заставляю перекомпоновывать

 var i = 0;
 for(;i<500;i+=50){
fTestInfo(i);
console.log("Test loop!!! "+i);
 }

Мне нужно видеть картинку на экране каждый раз, когда выполняется fTestInfo(i), но вместо этого я вижу только конечный результат.

fTestInfo зависит от i, он перемещается влево на значение i.


  • Вы уверены, что не анимируете все это в мгновение ока? Кроме того, без примера кода мы как бы в темноте. 03.08.2012

Ответы:


1

Я вижу, вы используете цикл for, который обычно означает, что вы неправильно понимаете, как работают таймеры. Цикл for выполняется синхронно, и вы, вероятно, устанавливаете все таймеры одновременно.

Попробуй это:

(function loop(i) {
    if (i >= 500) {
        return;
    }
    document.querySelector("div").style.left = i + "px";
    setTimeout(function() {
        loop(i + 1);
    }, 16);
})(0);

демо https://jsfiddle.net/UCfmF/


Полагаю, вы имеете в виду получение такого значения, как .offsetWidth? Это не гарантирует видимого перекомпоновки на экране, браузеры могут подождать некоторое время (читай: пока не прекратится выполнение javascript), прежде чем пытаться нарисовать что-либо на экране, даже если вы выполняете действия, вызывающие перекомпоновку.

Это означает, что если вы добавите в документ 1000 элементов, это не вызовет 1000 перекомпоновок. Даже если вы получаете .offsetWidth между каждой итерацией. Он будет просто рассчитан для вас, но не обязательно окрашен.

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

См. https://dev.opera.com/articles/view/efficient-javascript/?page=3#reflow

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

03.08.2012
  • Я отредактировал исходный пост. Я знаю об этом, как работают перекомпоновки, и я знаю, что я могу сделать 1000 элементов, а он может выполнить только одну перекомпоновку. Пробовал с таймером, ставил между этим логом и функцией, но только дольше жду, а результат тот же. Есть ли какое-то событие, которое я могу спровоцировать, которого не видно, и оно заставит переплавиться и покраситься? 06.08.2012
  • @Shakal187 Shakal187 покажи свой код, сейчас ты просто зацикливаешься, не используя тайм-ауты. 06.08.2012
  • У меня проблема с реализацией этого в моем коде. Нужна ли мне эта скобка перед циклом функции (i)? Я настоящий новичок в javascript 06.08.2012
  • @ Shakal187 Shakal187 да, вам нужно все, что у меня есть, за исключением, конечно, условия возврата, значения тайм-аута и манипулирования div. 06.08.2012
  • хорошо, спасибо, теперь это работает. У меня есть еще один вопрос. Это самый эффективный способ сделать это? Я имею в виду, есть ли более быстрые решения? 06.08.2012
  • @ Shakal187 Шакал187 не уверен, что ты имеешь в виду. Быстрее как? 06.08.2012
  • без рекурсии, например, или без этой временной задержки. Я работаю над встроенной системой, поэтому производительность также является проблемой :) 06.08.2012
  • @ Shakal187 Shakal187 нет рекурсии, стек вызовов всегда заканчивается в setTimeout - процессор фактически отдыхает между тайм-аутами. Тем не менее, использование браузера и javascript во встроенной системе не кажется хорошей идеей... 06.08.2012
  • Кстати, вы можете использовать чат javascript для обсуждения, так как комментарии на самом деле не разрешены для него. Вы можете принять ответ, щелкнув белую галочку слева от ответа, если ваша проблема была решена. 06.08.2012

  • 2

    Вам нужно дать браузеру возможность войти в свой цикл обработки событий между каждой итерацией.

    Используйте setTimeout для планирования каждой итерации рисования:

    function scheduledTestInfo(i) {
        setTimeout(function() {
            fTestInfo(i);
        }, i);  // calls each function 50ms apart
    }
    
    var i = 0;
    for ( ; i < 500 ; i += 50) {
        scheduledTestInfo(i);
    }
    
    06.08.2012
  • Обратите внимание, что это не сработает, если значение i будет увеличиваться менее чем на 13 за раз. И по-прежнему некрасиво делать несколько тайм-аутов одновременно, а не связывать их в цепочку, имхо: P 06.08.2012
  • Да, я знаю. Лучше не пытаться программировать 8 часов смены часовых поясов :( 06.08.2012
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]