簡體   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