我正在尝试制作响应式网站,但是我在尝试如何在iOS设备上禁用橡皮筋效果。禁用它的原因是希望使其更像一个应用程序而不是一个网站。
我已经找到了一些代码,但是它已经很老了,似乎没有人可以再回答它,所以我把我弄的东西放在了摆弄中,希望有人能提供帮助。
我需要的是一个页面,该页面允许用户向下滚动,然后在到达顶部或底部时停止,没有橡皮筋。
这是我发现的代码
(function registerScrolling($) {
var prevTouchPosition = {},
scrollYClass = 'scroll-y',
scrollXClass = 'scroll-x',
searchTerms = '.' + scrollYClass + ', .' + scrollXClass;
$('body').on('touchstart', function (e) {
var $scroll = $(e.target).closest(searchTerms),
targetTouch = e.originalEvent.targetTouches[0];
// Store previous touch position if within a scroll element
prevTouchPosition = $scroll.length ? { x: targetTouch.pageX, y: targetTouch.pageY } : {};
});
$('body').on('touchmove', function (e) {
var $scroll = $(e.target).closest(searchTerms),
targetTouch = e.originalEvent.targetTouches[0];
if (prevTouchPosition && $scroll.length) {
// Set move helper and update previous touch position
var move = {
x: targetTouch.pageX - prevTouchPosition.x,
y: targetTouch.pageY - prevTouchPosition.y
};
prevTouchPosition = { x: targetTouch.pageX, y: targetTouch.pageY };
// Check for scroll-y or scroll-x classes
if ($scroll.hasClass(scrollYClass)) {
var scrollHeight = $scroll[0].scrollHeight,
outerHeight = $scroll.outerHeight(),
atUpperLimit = ($scroll.scrollTop() === 0),
atLowerLimit = (scrollHeight - $scroll.scrollTop() === outerHeight);
if (scrollHeight > outerHeight) {
// If at either limit move 1px away to allow normal scroll behavior on future moves,
// but stop propagation on this move to remove limit behavior bubbling up to body
if (move.y > 0 && atUpperLimit) {
$scroll.scrollTop(1);
e.stopPropagation();
} else if (move.y < 0 && atLowerLimit) {
$scroll.scrollTop($scroll.scrollTop() - 1);
e.stopPropagation();
}
// If only moving right or left, prevent bad scroll.
if(Math.abs(move.x) > 0 && Math.abs(move.y) < 3){
e.preventDefault()
}
// Normal scrolling behavior passes through
} else {
// No scrolling / adjustment when there is nothing to scroll
e.preventDefault();
}
} else if ($scroll.hasClass(scrollXClass)) {
var scrollWidth = $scroll[0].scrollWidth,
outerWidth = $scroll.outerWidth(),
atLeftLimit = $scroll.scrollLeft() === 0,
atRightLimit = scrollWidth - $scroll.scrollLeft() === outerWidth;
if (scrollWidth > outerWidth) {
if (move.x > 0 && atLeftLimit) {
$scroll.scrollLeft(1);
e.stopPropagation();
} else if (move.x < 0 && atRightLimit) {
$scroll.scrollLeft($scroll.scrollLeft() - 1);
e.stopPropagation();
}
// If only moving up or down, prevent bad scroll.
if(Math.abs(move.y) > 0 && Math.abs(move.x) < 3){
e.preventDefault();
}
// Normal scrolling behavior passes through
} else {
// No scrolling / adjustment when there is nothing to scroll
e.preventDefault();
}
}
} else {
// Prevent scrolling on non-scrolling elements
e.preventDefault();
}
});
})(jQuery);
最佳答案
您还可以在HTML + JS端执行此操作,前提是HTML文档不高于WebView视口(JS中也称为window.height)。您可以通过在适当的时候在'touchmove'事件上调用preventDefault来做到这一点(即,当元素及其所有父元素都没有向用户开始移动其手指的方向滚动时)。
我将向您展示实际的代码,而不使用jQuery ...,但是您必须自己实现Q.addEventListener和Q.removeEventListener(或使用jQuery)。
var Q = {
preventTouchScrolling: function () {
Q.addEventListener(window, 'touchmove', _touchScrollingHandler);
},
restoreTouchScrolling: function () {
Q.removeEventListener(window, 'touchmove', _touchScrollingHandler);
},
Pointer: {
/**
* Consistently prevents the default behavior of an event across browsers
* @static
* @method preventDefault
* @param {Event} e Some mouse or touch event from the DOM
* @return {Boolean} Whether the preventDefault succeeded
*/
preventDefault: function (e) {
if (('cancelable' in e) && !e.cancelable) {
return false;
}
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return true;
},
/**
* Returns the document's scroll top in pixels, consistently across browsers
* @static
* @method scrollTop
* @return {Number}
*/
scrollTop: function () {
return window.pageYOffset || document.documentElement.scrollTop || (document.body && document.body.scrollTop);
},
/**
* Returns the y coordinate of an event relative to the document
* @static
* @method getY
* @param {Event} e Some mouse or touch event from the DOM
* @return {Number}
*/
getY: function(e) {
var oe = e.originalEvent || e;
oe = (oe.touches && oe.touches.length)
? oe.touches[0]
: (oe.changedTouches && oe.changedTouches.length
? oe.changedTouches[0]
: oe
);
return Math.max(0, ('pageY' in oe) ? oe.pageY : oe.clientY + Q.Pointer.scrollTop());
},
}
};
function _touchScrollingHandler(event) {
var p = event.target;
var pos;
var scrollable = null;
do {
if (!p.computedStyle) {
continue;
}
var overflow = p.computedStyle().overflow;
var hiddenHeight = p.scrollHeight - p.offsetHeight;
var s = (['hidden', 'visible'].indexOf(overflow) < 0);
if ((s || p.tagName === 'HTML') && hiddenHeight > 0) {
if ((Q.Pointer.movement.positions.length == 1)
&& (pos = Q.Pointer.movement.positions[0])) {
var sy = Q.Pointer.getY(event)
+ Q.Pointer.scrollTop();
if ((sy > pos.y && p.scrollTop == 0)
|| (sy < pos.y && p.scrollTop >= hiddenHeight)) {
continue;
}
}
scrollable = p;
break;
}
} while (p = p.parentNode);
if (!scrollable) {
Q.Pointer.preventDefault(event);
}
}