0

私は現在、ネイティブスクロールを使用して大きな棒グラフ svg を表示する iPad JS/HTML アプリに取り組んでいます。

x 軸と y 軸に沿ったラベル付けがグラフの上部と左側に保持されるようにしています。基本的に、グラフはラベルの下を自由にスライドする必要があり、ラベル自体は適切な方向にのみ移動します (たとえば、左にスクロールすると x 軸のヘッダーがラベルを移動し、垂直スクロールの場合は y 軸のラベルが移動します)。

現在、これを行うための css がありますが、ネイティブ スクロールは、パネルを同期するための JavaScript よりもはるかに高速に移動します。ある要素が他の要素よりも速くドラッグされるため、このような弾力的な相互作用があります。スクロール アニメーションが停止すると、すべてが正しい場所に表示されますが、スクロール中の操作は非常にぎこちなく見えます。

この問題に取り組むためのより良い方法はありますか? 私が利用できる他のイベントはありますか?手動で js 位置を計算せずに、複数のスクロール可能な div を同じスクロール イベントに強制的に反応させる方法はありますか? それとも、ネイティブ スクロールが GPU にオフロードされているため、遅延は避けられませんか?

/* CSS */
.fixedaxis {
    position:absolute;
    top: 0px;
    left: 0px;
    background: blue;
}

#chartheader {
    z-index:5; 
}

#sidebar {
    z-index:6;
}

    .scroll {
        overflow: auto;
        -webkit-overflow-scrolling: touch;
    }



/* relevant html */

    <div id="content" style="position: relative;">
        <div id="chartheader" class="fixedaxis"></div>
        <div id="sidebar" class="fixedaxis"></div>
        <div class="scroll">
            <section id="barchart">
            </section>
         </div>
     </div>

/*javascript */

var scroller = $('.scroll');
var tableHeader = $('#chartheader');
var sidebar = $('#sidebar');
scroller.on('scroll', function() {
    console.log("scrolling: " + this.scrollLeft);
    tableHeader.css('left', (-1 * this.scrollLeft) + 'px');
    sidebar.css('top', (-1 * this.scrollTop) + 'px');
});
4

1 に答える 1

0

結局のところ、あなたはできません。少なくとも、現時点ではそうではありません。

Apple Developer ドキュメントによると https://developer.apple.com/library/ios/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

ユーザーの指が画面上にあるときにスクロールのイベントを受け取り、勢いが止まると 1 つの最後のスクロール イベントを受け取ります。これらの 2 つの期間の間でコンテンツが移動している場合、イベントは発生しません。

最終的には、2 回目のスクロール イベントでサイドバーのコンテンツを半透明にし、タイムアウト後に再び不透明にし、単一の「モメンタム エンド」スクロール イベントが再び発生した場合に位置を変更できるようにしました。

次のようなもの:

           var lastTimeout;
           var numScrolls = 1;
           var startTop = 0;

           function(event) {
                var elem = event.target;
                startTop = startTop || elem.scrollTop;

                if (lastTimeout) {
                    clearTimeout(lastTimeout);
                } else if (numScrolls == -1) {
                   /* I've omitted some short circuit logic for other scrolling cases
                    * but that's why we're going off of -1 here 
                    */

                    // stray scroll from native scroll end
                    $labels[0].scrollTop = elem.scrollTop;
                    $labels.css('opacity', '1');
                    startTop = null;
                }


                // wait for two consecutive scrolls
                if (numScrolls > 0) {
                    $labels.css('opacity', '0.3');
                }

                ++numScrolls;
                lastTimeout = setTimeout(function() {
                    console.log(elem.scrollTop);
                    $labels[0].scrollTop = elem.scrollTop;
                    $labels.css('opacity', '1');
                    lastTimeout = null;
                    numScrolls = -1;
                    startTop = null;
                }, 1000);
            };
于 2012-05-17T17:56:07.837 に答える