Jef*_*eff 98 safari jquery mobile-website ipad ios
我正在开发一个基于iPad的网络应用程序,需要防止过度滚动,以免它看起来像网页.我目前正在使用它来冻结视口并禁用过度滚动:
document.body.addEventListener('touchmove',function(e){
      e.preventDefault();
  });
这可以很好地禁用过度滚动,但我的应用程序有几个可滚动的div,上面的代码阻止它们滚动.
我只针对iOS 5及以上版本,所以我避免使用像iScroll这样的hacky解决方案.相反,我将这个CSS用于我的可滚动div:
.scrollable {
    -webkit-overflow-scrolling: touch;
    overflow-y:auto;
}
这没有文档overscroll脚本,但不解决div滚动问题.
没有jQuery插件,有没有办法使用过度滚动修复但免除我的$('.scrollable')divs?
编辑:
我发现了一些不错的解决方案:
 // Disable overscroll / viewport moving on everything but scrollable divs
 $('body').on('touchmove', function (e) {
         if (!$('.scrollable').has($(e.target)).length) e.preventDefault();
 });
滚动浏览div的开头或结尾时,视口仍会移动.我想找到一种方法来禁用它.
小智 84
滚动浏览div的开头或结尾时,这可以解决问题
var selScrollable = '.scrollable';
// Uses document because document will be topmost level in bubbling
$(document).on('touchmove',function(e){
  e.preventDefault();
});
// Uses body because jQuery on events are called off of the element they are
// added to, so bubbling would not work if we used document instead.
$('body').on('touchstart', selScrollable, function(e) {
  if (e.currentTarget.scrollTop === 0) {
    e.currentTarget.scrollTop = 1;
  } else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
    e.currentTarget.scrollTop -= 1;
  }
});
// Stops preventDefault from being called on document if it sees a scrollable div
$('body').on('touchmove', selScrollable, function(e) {
  e.stopPropagation();
});
请注意,如果您想在div没有溢出时阻止整页滚动,这将不起作用.要阻止它,请使用以下事件处理程序而不是上面的事件处理程序(根据此问题改编):
$('body').on('touchmove', selScrollable, function(e) {
    // Only block default if internal div contents are large enough to scroll
    // Warning: scrollHeight support is not universal. (https://stackoverflow.com/a/15033226/40352)
    if($(this)[0].scrollHeight > $(this).innerHeight()) {
        e.stopPropagation();
    }
});
Kub*_*luj 23
使用Tyler Dodge的优秀答案一直滞后于我的iPad,所以我添加了一些限制代码,现在它非常流畅.滚动时有时会有一些最小的跳过.
// Uses document because document will be topmost level in bubbling
$(document).on('touchmove',function(e){
  e.preventDefault();
});
var scrolling = false;
// Uses body because jquery on events are called off of the element they are
// added to, so bubbling would not work if we used document instead.
$('body').on('touchstart','.scrollable',function(e) {
    // Only execute the below code once at a time
    if (!scrolling) {
        scrolling = true;   
        if (e.currentTarget.scrollTop === 0) {
          e.currentTarget.scrollTop = 1;
        } else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
          e.currentTarget.scrollTop -= 1;
        }
        scrolling = false;
    }
});
// Prevents preventDefault from being called on document if it sees a scrollable div
$('body').on('touchmove','.scrollable',function(e) {
  e.stopPropagation();
});
此外,添加以下CSS修复了一些渲染故障(源):
.scrollable {
    overflow: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
}
.scrollable * {
    -webkit-transform: translate3d(0,0,0);
}
Jon*_*nge 12
首先像往常一样阻止整个文档的默认操作:
$(document).bind('touchmove', function(e){
  e.preventDefault();           
});
然后停止您的元素类传播到文档级别.这会阻止它到达上面的函数,因此不会启动e.preventDefault():
$('.scrollable').bind('touchmove', function(e){
  e.stopPropagation();
});
这个系统似乎比在所有触摸动作上计算类更自然且更少密集.对动态生成的元素使用.on()而不是.bind().
还要考虑这些元标记,以防止在使用可滚动div时发生不幸事件:
<meta content='True' name='HandheldFriendly' />
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0' name='viewport' />
<meta name="viewport" content="width=device-width" />
您是否可以在过度滚动禁用代码中添加更多逻辑,以确保有问题的目标元素不是您想要滚动的元素?像这样的东西:
document.body.addEventListener('touchmove',function(e){
     if(!$(e.target).hasClass("scrollable")) {
       e.preventDefault();
     }
 });
对此最好的解决方案是css/html:创建一个div来包装你的元素,如果你还没有它并将它设置为固定位置和溢出隐藏.可选,如果您希望它填满整个屏幕,除了整个屏幕之外,只需将高度和宽度设置为100%
#wrapper{
  height: 100%;
  width: 100%;
  position: fixed;
  overflow: hidden;
}<div id="wrapper">
  <p>All</p>
  <p>Your</p>
  <p>Elements</p>
</div>小智 5
在尝试向下滚动时检查可滚动元素是否已滚动到顶部,或者在尝试向下滚动时检查是否已滚动到底部,然后阻止默认操作停止整个页面移动.
var touchStartEvent;
$('.scrollable').on({
    touchstart: function(e) {
        touchStartEvent = e;
    },
    touchmove: function(e) {
        if ((e.originalEvent.pageY > touchStartEvent.originalEvent.pageY && this.scrollTop == 0) ||
            (e.originalEvent.pageY < touchStartEvent.originalEvent.pageY && this.scrollTop + this.offsetHeight >= this.scrollHeight))
            e.preventDefault();
    }
});