Ответ 1
Значение "прокрутки" не зависит от размера окна или разрешения экрана. "Прокрутка" - это просто число прокрутки пикселей.
Однако, можете ли вы вообще прокручивать, а сумма, которую вы можете прокручивать, основана на доступной недвижимости для контейнера и размерах содержимого в контейнере (в этом случае контейнер равен document.documentElement
, или document.body
для старых браузеров).
Вы правы, что событие scroll
не содержит этой информации. Он не предоставляет свойство delta
для указания количества прокрученных пикселей. Это относится к собственному событию scroll
и событию jQuery scroll
. Кажется, что это была бы полезная функция, похожая на то, как события mousewheel
предоставляют свойства для X и Y дельта.
Я не знаю и не буду размышлять о том, почему полномочия, которые не предоставили свойство delta
для scroll
, но это выходит за рамки этого вопроса (не стесняйтесь публиковать отдельный вопрос об этом).
Метод, который вы используете для хранения scrollTop
в переменной и сравнивая его с текущим scrollTop
, является лучшим (и единственным) методом, который я нашел. Однако вы можете упростить это, расширив jQuery, чтобы предоставить новое настраиваемое событие в этой статье: http://learn.jquery.com/events/event-extensions/
Вот пример расширения, который я создал, который работает с прокруткой окна/документа. Это настраиваемое событие под названием scrolldelta
, которое автоматически отслеживает дельта X и Y (как scrollLeftDelta
и scrollTopDelta
, соответственно). Я не пробовал это с другими элементами; оставляя это как упражнение для читателя. Это работает в точных версиях Chrome и Firefox. Он использует трюк для получения суммы document.documentElement.scrollTop
и document.body.scrollTop
для обработки ошибки, в которой Chrome обновляет body.scrollTop
вместо documentElement.scrollTop
(обновление IE и FF documentElement.scrollTop
, см. https://code.google.com/p/chromium/issues/detail?id=2891).
JSFiddle demo: http://jsfiddle.net/tew9zxc1/
Runnable Snippet (прокрутите вниз и нажмите Run code snippet
):
// custom 'scrolldelta' event extends 'scroll' event
jQuery.event.special.scrolldelta = {
delegateType: "scroll",
bindType: "scroll",
handle: function (event) {
var handleObj = event.handleObj;
var targetData = jQuery.data(event.target);
var ret = null;
var elem = event.target;
var isDoc = elem === document;
var oldTop = targetData.top || 0;
var oldLeft = targetData.left || 0;
targetData.top = isDoc ? elem.documentElement.scrollTop + elem.body.scrollTop : elem.scrollTop;
targetData.left = isDoc ? elem.documentElement.scrollLeft + elem.body.scrollLeft : elem.scrollLeft;
event.scrollTopDelta = targetData.top - oldTop;
event.scrollTop = targetData.top;
event.scrollLeftDelta = targetData.left - oldLeft;
event.scrollLeft = targetData.left;
event.type = handleObj.origType;
ret = handleObj.handler.apply(this, arguments);
event.type = handleObj.type;
return ret;
}
};
// bind to custom 'scrolldelta' event
$(window).on('scrolldelta', function (e) {
var top = e.scrollTop;
var topDelta = e.scrollTopDelta;
var left = e.scrollLeft;
var leftDelta = e.scrollLeftDelta;
// do stuff with the above info; for now just display it to user
var feedbackText = 'scrollTop: ' + top.toString() + 'px (' + (topDelta >= 0 ? '+' : '') + topDelta.toString() + 'px), scrollLeft: ' + left.toString() + 'px (' + (leftDelta >= 0 ? '+' : '') + leftDelta.toString() + 'px)';
document.getElementById('feedback').innerHTML = feedbackText;
});
#content {
/* make window tall enough for vertical scroll */
height: 2000px;
/* make window wide enough for horizontal scroll */
width: 2000px;
/* visualization of scrollable content */
background-color: blue;
}
#feedback {
border:2px solid red;
padding: 4px;
color: black;
position: fixed;
top: 0;
height: 20px;
background-color: #fff;
font-family:'Segoe UI', 'Arial';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='feedback'>scrollTop: 0px, scrollLeft: 0px</div>
<div id='content'></div>