繁体   English   中英

在一个轴上使用原生滚动进行iScroll

[英]iScroll with native scrolling on one axis

我在iOS和Android的移动网站上使用最精彩的JavaScript工具iScroll4 http://cubiq.org/iscroll-4 这是我的布局:

布局问题

水平滚动区域使用iScroll4进行以下设置:

   var myScroll = new iScroll('frame',  { hScrollbar: false, vScrollbar: false, vScroll: false })

水平滚动部分效果很好。 此问题是当用户尝试向上或向下滚动页面时将手指放在水平滚动区域上时会发生的问题。 所以我需要原生垂直滚动,并在同一区域上进行iScroll水平滚动。

到目前为止我尝试过:在iScroll代码中删除e.preventDefault()(允许本地滚动,但在BOTH轴中)。 删除e.preventDefault()然后禁用水平滚动页面宽度:

var touchMove;

document.ontouchstart = function(e){
    touchMove = e.touches[0];
}

document.ontouchmove = function(e){
    var theTouch = e.touches[0] || e.changedTouches[0];
    var Xer      = rs(touchMove.pageX - theTouch.pageX).toPos();
    var Yer      = rs(touchMove.pageY - theTouch.pageY).toPos();        
    touchMove    = theTouch;
    if(Yer > Xer){ e.preventDefault(); }
}

这似乎无能为力。 如何在水平滚动区域中允许原生垂直滚动,而不会丢失iScroll的水平滚动? 我真的很难过。 提前致谢。

(仅用于记录rs(foo).toPos()是一个使foo成为正数的函数,无论其值如何)。

如果您希望在不破坏核心的情况下实现Fresheyeball描述的效果,并且无需从iScroll更改为swipeview,那么iScroll 4确实为您提供了可以使用的事件监听器。

myScroll = new iScroll('scrollpanel', {
    // other options go here...
    vScroll: false,
    onBeforeScrollMove: function ( e ) {
        if ( this.absDistX > (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        } else {
            // delegate the scrolling to window object
        window.scrollBy( 0, -this.distY );
    }
    },
});

通过这样做, onBeforeScrollMove -Handler检查滚动方向是否是水平的,然后阻止默认处理程序,从而有效地将滚动操作锁定到X轴(尝试将其注释掉,你会看到差异)。 否则,如果滚动方向需要是垂直的,我们通过window.scrollBy()方法滚动浏览器。 这不完全是原生的,但是工作做得很好。

希望有所帮助

Lukx

[编辑]我的原始解决方案,没有使用window.scrollBy() ,在较慢的三星手机上不起作用,这就是我需要调整答案的原因。

建议编辑@Lukx的优秀解决方案。 新版本的iScroll4将e.preventDefault()放在onBeforeScrollMove ,可以覆盖它。 通过将if块放入此选项,不会阻止垂直滚动的默认值,而vertical可以本机滚动。

myScroll = new iScroll('scrollpanel', {
    // other options go here...
    vScroll: false,
    onBeforeScrollStart: function ( e ) {
        if ( this.absDistX > (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        }
    },
});

使用iscroll 5,您可以设置eventPassthrough: true来实现此目的。 请参阅http://iscrolljs.com/#configuring

老答复

更新了一个特殊的插件,只是为了解决这个问题: http//cubiq.org/swipeview

我找到了一个方法!

在文档的顶部添加一个变量:如果android是15并且iOS是3

 var scrollTolerance = ( rs().isDevice('android') )?15:3;

禁用原始的e.preventDefault(); 滚动。 这是在onBeforeScrollStart下:

in _move就在下面

 timestamp = e.timeStamp || Date.now();

添加此行

if( Math.sqrt(deltaX*deltaX) > scrollTolerance){e.preventDefault();}

这样做的原因如下:你猜对了scrollTolerance设置了手指方向的容差。 我们不希望要求一个完美的垂直角度来获得向上的原生卷轴。 iOS也没有正确检测,并且由于某种原因永远不会高于4,所以我使用3.然后我们禁用iScroll的标准e.preventDefault(); 这会阻止我们的双滚动区域上的原生垂直滚动。 然后我们插入e.preventDefault(); 仅在移动时并且基于手指方向的公差。

这不是完美的。 但是可以接受,适用于iOS和Android。 如果有人看到更好的方式,请在这里发布 这是我(并假设其他人)需要定期使用的东西,我们应该有一个完美的坚如磐石的解决方案。

谢谢。

请从亚当测试这个解决方案。 https://gist.github.com/hotmeteor/2231984

我认为诀窍是在onBeforeScrollMove中添加检查。 首先获取onBeforeScrollTouchStart中的初始触摸位置,然后在onBeforeScrollMove中检查新位置,然后根据差异禁用所需的滚动。

iScroll 5支持任意轴的原生滚动!

http://iscrolljs.com/

在iScroll5上只需将eventPassthrougt设置为true即可。 这解决了它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM