Недавно я нашел очень странное (на мой взгляд) окно window.scrollTo в Safari (6.0.5 (8536.30.1), MacOS 10.8.4). Кажется, он работает асинхронно.
Моя задача звучит так:
- установите фиксированное положение абсолютного положения div (выведите его)
- выполнить прокрутку страницы
- сделать ранее измененный div, чтобы он был полностью расположен назад (отменить)
Итак, чтобы разблокировать этот div, я должен выполнить процедуру unpin сразу после завершения модификации прокрутки. И здесь я столкнулся с проблемой. Каждый проверенный мной браузер делает это правильно, кроме Safari.
Шаги для воспроизведения:
- Откройте любую веб-страницу в Safari и убедитесь, что она прокручивается, по крайней мере, для 100px, и начальное смещение прокрутки - 0
- Откройте консоль js в инструментах разработчика
- выполнить:
window.scrollTo(0, 100); console.log(document.body.scrollTop);
Выход равен 0. Но когда я меняю этот код на window.scrollTo(0, 100); window.setTimeout(function() {console.log(document.body.scrollTop)}, 1);
, результат равен 100.
Вот все другие браузеры, которые я тестировал (где он работает нормально):
- Chrome 27.0.1453.110 (MacOS 10.8.4)
- Firefox 21.0 (MacOS 10.8.4)
- Opera 12.15 b1748 (MacOS 10.8.4)
- IE 8.0.7601.17514 (Win7)
Хорошо, как только мой пример кода не является перекрестным браузером, проще проверить это поведение на любой веб-странице с помощью jQuery:
var $w = $(window);
$w.scrollTop(100);
console.log($w.scrollTop());
VS
var $w = $(window);
$w.scrollTop(100);
window.setTimeout(function() {
console.log($w.scrollTop())
}, 1);
Это нормально, или это ошибка? Как с этим справиться? (Теперь я изменил $.fn.scrollTop
, чтобы вернуть $.Deferred
вместо цепочки и мгновенно разрешить его в основном потоке во всех браузерах, кроме Safari).