Обратный вызов jQuery происходит в необычной последовательности (в основном в Chromium/chrome)

Это так же "как это на самом деле должно работать?" так как это "почему, черт возьми, это не работает?" запрос.

Я использую jQuery animate() для роста и сжатия div на моей странице. У меня есть одна функция, которая переключает между двумя состояниями, проверяя, имеет ли элемент "более крупный" класс и условно растет или сокращается. Вот так:

function toggleBox(thisBox)
{
 if($("#" + thisBox).hasClass('bigger')) // Shrink it if it big
 {
 $("#" + thisBox).animate({ height: '44px'},500).removeClass("bigger");
 }
 else // grow it
 {
 $("#" + thisBox).addClass("bigger").animate({ height: '40%' },500);
 }
}

Это абсолютно персик, с одной маленькой проблемой. Я использую CSS, чтобы дать определенные элементы вертикальных полос прокрутки, если и только если они имеют класс ".bigger". Это вызывает проблему с некоторыми элементами, поскольку у них есть дочерние объекты с относительной шириной, которые не подвергаются повторной рендерингу во всех браузерах, когда вертикальная полоса прокрутки на месте (в данном случае Chrome/Chromium является основным нарушителем).

Чтобы заставить дочерние объекты изменять размер при вызове указанной функции, я попробовал следующее решение для ham-fisted:

function toggleBox(thisBox)
{
 if($("#" + thisBox).hasClass('bigger')) // Shrink it if it big
 {
 $("#" + thisBox).animate({ height: '44px'},500).removeClass("bigger");
 }
 else // grow it
 {
 $("#" + thisBox).addClass("bigger").animate({ height: '40%' },500, 'swing', function()
 {
 $(".rerender").each(function()
 {
 this.className = this.className;
 // Or something similar; I've tried a few methods
 console.log(this.className); // Just to check
 });
 });
 }
}

Итак, все, что мне нужно для повторной рендеринга, когда его родительский div изменил размер, просто нуждается в классе ".rerender", и он будет восстанавливать все свойства CSS.

Есть две проблемы с этим: во-первых, все, что я использую в обратном вызове, который я использую для изменения CSS, будь то jQuery или javascript, похоже, работает одновременно с вызываемой им функцией, но другие script содержимое в обратном вызове запускается, когда вызывающая функция завершена, как и предполагалось. В script выше, например, все, что я добавил в обратном вызове для изменения CSS, уже произошло к моменту завершения .animate(), но console.log() не завершится до тех пор, пока .animate(). Это происходит, даже если я вызываю код, влияющий на CSS, из console.log()!

Вторая проблема заключается в том, что любое одно событие, которое я использую для принудительного повторного рендеринга объекта (удаление и повторное добавление класса или даже изменение значения свойства CSS для другого значения), на самом деле не вызывает объект для повторной обработки. Если я сделаю что-то вроде $('#theObject').removeClass('theClass').addClass('theClass'); или даже

function()
{
 $('#theObject').removeClass('theClass');
 $('#theObject').addClass('theClass');
}

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

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

1 ответ

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

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

licensed under cc by-sa 3.0 with attribution.