Попробуйте это.
See it in a JS Fiddle
function scrollingSlider(selector, beginpos, endpos) {
var slide,
timeout = 0;
slide = function() {
var scrollpos;
window.clearTimeout(timeout);
timeout = 0;
scrollpos = $(window).scrollTop();
$(selector).each(function() {
var $this = $(this),
margintarget,
margin = parseInt($this.css('margin-left'), 10),
step;
if (scrollpos <= beginpos) {
margintarget = -1000;
} else if (scrollpos >= endpos) {
margintarget = 0;
} else {
margintarget = Math.round(-1000 * (endpos - scrollpos)/(endpos - beginpos));
}
if (margintarget === margin) {
return; // nothing more to do
}
step = margintarget - margin;
if (Math.abs(step) > 25) {
step = 25 * (step < 0 ? -1 : 1);
}
$this.css('margin-left', margin + step);
if (!timeout && (margin + step) !== margintarget) {
timeout = window.setTimeout(slide, 10);
}
});
};
$(window).on('scroll', slide);
}
$(document).ready(function(){
scrollingSlider('.post-129, .post-169', 100, 300);
});
Примечание
Чтобы использовать функцию scrollingSlider
, передать в селекторе JQuery, положение scrolltop в пикселях, с которого начинается скольжение, и положение scrolltop в пикселях в который должен быть полным. Если вы используете селектор строк, вы избежите потенциальной проблемы создания замыкания над элементами DOM, которые могут помешать освобождению памяти в сценариях интенсивного использования.
Positioning
Кроме того, я рекомендую вместо того, чтобы использовать положение прокрутки, чтобы определить, когда, чтобы показать элементы, которые вместо того, чтобы изменить код, чтобы скользить вещи в зависимости от места топовой каждого элемента сравнивается с как далеко он находится на виду в нижней части окна прокрутки. Это достигается двумя вещами:
- Если вы изменили свою страницу, чтобы добавить или удалить контент (таким образом, изменив вертикальное расположение ваших элементов), вы не будете работать с ошибками.
- Что еще более важно, для тех, у кого большой экран достаточно большой, чтобы содержать всю страницу, они никогда не смогут увидеть ваши вставные элементы, потому что у них нет полосы прокрутки! Связывание видимости вещей с положением полосы прокрутки (а не расстояния, которое элемент должен войти в окно просмотра) - хороший способ сделать ваш контент совершенно недоступным - возможно, не то, что вы ищете. Примечание: мой текущий экран имеет высоту 2880 пикселей, и если бы я повернул его в портретном режиме, это было бы 5120 пикселей в высоту. Это лот веб-страницы, видимой сразу. Вместив эти большие размеры экрана, вы должны тщательно подумать. Вы можете поиграть с добавлением какого-либо дополнения или интервала в нижней части страницы, которая зависит от высоты окна, заставляя полосы прокрутки появляться и использоваться (что означает, что прокрутка в нижнюю часть приводит к тому, что самый низкий видимый элемент находится или за пределами наверх страницы, а не внизу).
Еще одно примечание: я полностью отказался от opacity
. Проблема была в том, что в CSS вы должны сказать -1000px
, поскольку -1000
не имеет единицы и игнорируется. Единственный раз, когда вы не можете использовать устройство, - 0
- иначе, как браузер узнает, что вы имеете в виду пиксели, а не, скажем, em
s ?.
Правда, я не использовал возможности анимации jQuery. Вероятно, я мог бы это сделать. Вместо того, чтобы устанавливать мой собственный тайм-аут, чтобы снова запустить функцию, я мог просто сказать jQuery, чтобы анимировать элемент в правильной позиции, сначала с .stop()
, чтобы остановить любую выдающуюся анимацию. Это было бы совершенно справедливо. На этот раз я сделал это так. Не стесняйтесь изменять.
Объяснение
Настройка начального триггера для откатных быть scroll
событие. В функции slide
для каждого интересующего нас элемента рассчитываем левое поле цели, которое мы хотим сдвинуть, на основе текущей позиции прокрутки. Переместите элемент не более чем на 25 пикселей к этой цели. Если целевое положение не достигнуто, установите таймер, чтобы повторить этот процесс. Поскольку событие прокрутки не только может радикально изменить целевое положение, но и может настроить собственный каскад анимации, отмените любой выдающийся таймер, который установлен в начале функции slide
.
Скорость Соображение
Если вы обнаружили, что 10мс слишком часто и анимация коренастая или слишком ресурсоемкий, поднимите его, так что функция пожары реже, увеличивая максимальный шаг, подобным фактором (в настоящее время 25). Если анимация слишком медленная или слишком быстрая, увеличьте или уменьшите максимальный шаг соответственно.
Дальнейшие идеи по улучшению скорости:
В вашем веб-сайте, есть другой код, работающий в то же время, что это предотвращает функцию слайд от вызова до того 10мс вверх. Тогда происходят странные вещи.
Используйте ids вместо классов на своих скользящих элементах.
Как и было предложено, измените время ожидания на что-то вроде 40 мс или 100 мс и увеличьте максимальное количество пикселей, перемещаемых объектом аналогичным образом.
В вашем целевом сценарии использования ваши два изображения заперты вместе, поэтому выньте функцию each
и просто выполните операцию одновременно в обоих случаях - это должно привести к значительному сокращению времени выполнения.
Последнее, примечание об использовании: не следует включать сценарий несколько раз для анимации нескольких объектов. Вместо этого просто позвоните scrollingSlider
несколько раз в функции ready
!
UPDATE
Пожалуйста, смотрите раздел «Позиционирование» выше, которая была обновлена с новой и важной информацией о размерах экрана.
Я не понимаю, что вы имеете в виду. По крайней мере, в Firefox, divs не перекрываются. И что означает «сближение, когда вы прокручиваетесь», и что означает «перемещение в центр в соответствии с положениями прокрутки»? Это просто не ясно. Подождите ... Вы хотите сказать, что вы хотите, чтобы divs постепенно скользили на основе точной высоты полосы прокрутки, а не просто прокручивали весь путь или из-за порога? – ErikE
Да, это именно то, что я имею в виду. жаль, что он расплывчатый, с трудом пытался объяснить.Перекрытие не происходит в jsfiddle, но на моем веб-сайте я могу исправить это самостоятельно, используя css. –
Вздох. У меня была отличная идея, она была закодирована в jsfiddle, затем тупо ударила обновление и потеряла все. Добрый день. – ErikE