禁用橡皮筋效果但仍允许使用jquery滚动

时间:2014-01-23 15:55:16

标签: jquery css

我正在努力制作响应式网站,但我正在努力解决如何在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);

1 个答案:

答案 0 :(得分:0)

您也可以在HTML + JS端执行此操作,前提是HTML文档高于WebView视口(在JS中称为window.height)。你可以通过在&#39; touchmove&#39;上调用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);
    }
}