web-dev-qa-db-ja.com

タッチデバイスのscrollTopを確認します

ユーザーのスクロール位置をチェックして、マストヘッドを超えてスクロールするとメニューが固定されるようにする次の機能があります

function checkScrolling() {
    if( $(window).scrollTop() > $('.masthead').height() ) { // we check against ACTUAL height
        $('.menu').addClass('fixed');
    }else {
        $('.menu').removeClass('fixed');
    }
}

ここでは、デスクトップとタッチスクリーンのイベントリスナー:

$(document).bind('touchstart touchend touchcancel touchleave touchmove', function(e){
    checkScrolling();
});

$(window).scroll(function(){
    checkScrolling();
});

ただし、タッチイベントは、タッチ移動中にメニューを確実に修正するだけです。上または下にスワイプして非常に速くスクロールすると、メニューが固定または固定解除されるまでに遅延が発生します。

これを修正する方法についてのアイデアはありますか? ここでコード例を参照してください: http://dev.driz.co.uk/mobileMasthead.html (以下のいくつかの回答に基づいて修正されましたが、それでもiPadまたはiPhoneでは正しく動作しません)

更新:そしてトピックを読むと、スクロール位置をチェックするようなJSはスクロール中には発生しないことがわかります...しかし... iPadでテストしたところ、 http://www.facebook.com/home/ にはこの問題がないことに気づきました。したがって、iScrollなどのカスタムJavaScriptスクロールバーを使用せずに、この効果を実現することは間違いなく可能です。

18
Cameron

質問が間違っていることは理解しているかもしれませんが、高速スクロールで機能を確保するために、純粋なCSSの方法(別名「ファンシー」効果)に取り組んでみませんか?

オールドスクール(速いが原始的)

[〜#〜] html [〜#〜]

<div id="menu2"></div>
    <div class="scroll" id="scroller">
        <div id="overlay"></div>
        <div id="menu"></div>
    </div>

単純なCSSの場合:

html, body { overflow: hidden; height: 100% }
body { margin:0; padding:0; }

 .scroll {
     -webkit-overflow-scrolling: touch;
     height:960px;
     width:640px;
 }

 #menu2 {
     width:640px;
     height:20px;
     background:red;
     position:absolute;
     z-index:-1;
 }

 #menu {
     width:100%;
     height:20px;
     background:red;
     z-index:0;
 }

実例を見ることができます [〜#〜]ここ[〜#〜]

それは少し原始的かもしれません:しかしねえ!できます! :)

新しい学校(派手だが遅い)

提供された他のすべての回答を確認してください。

ただし、JavaScriptをモバイルデバイスでのスクロールと組み合わせて使用​​すると、速度に関して多くの問題が発生することが「知られている」ことに注意してください。

だからこそ、単純なCSSアプローチの方が良いと思います。

JavaScriptとモバイルデバイス(およびその他の機能)でのスクロールについて学びたい場合は、2つの記事を読むことを強くお勧めします。

7
Jean-Paul

FacebookはJavaScriptを使用しませんが、純粋なcssを使用します。

position: -webkit-sticky;

私がそれを正しく覚えていれば、これはスクロールされたときに要素をその親コン​​テナの上部に固定します。

5
a better oliver

私はかつてモバイル版のサイトにスティッキーヘッダーを実装しようとしましたが、一連の問題に遭遇しました。

まず、最も重要なのは、scrollイベントは、デスクトップよりもモバイルデバイスで頻繁に発生しないことです。通常、ページが停止すると起動します。その正確な理由はわかりませんが、モバイルのブラウザがそのようなタスクをGPUに「送信」している間、CPUはJSオブジェクトをキャンバスに何が起こっているかを最新に保つことができないためです(しかし、それは私の提案です)。 iOSの新しいバージョンは私たちにとってそれをより良くしており、おそらくscrollはiPhoneで動作するでしょう。

touchイベントを使用する必要があります。これにより、タッチ入力をサポートするデバイス用に別のバージョンのコードを作成できます。したがって、プラットフォームをテストするための信頼できる方法を探す必要があります。

ただし、touchイベントは、特にAndroidでは注意が必要です。 touchmoveイベントのコールバックで、現在の座標を把握し、そのポイントからさらに進むことができると思いました。

しかし、この問題があります https://code.google.com/p/Android/issues/detail?id=5491 Androidの場合、要約すると、touchmoveは非常に1回または2回発生しますタッチアクションの開始であり、再び発火することはありません。それはそれを完全に役に立たないものにします。人々はpreventDefault()を提案していますが、それでスクロールすることはできなくなりました。

そのため、CSS変換を使用してスクロールを最初から再実装するというアイデアにたどり着きました。そして、これがこれまでの私の結果です:

http://jsbin.com/elaker/2

デバイスでそのリンクを開き、デスクトップで http://jsbin.com/elaker/23/edit :コードを編集できるようになり、デバイス上でライブアップデートが行われます。非常に便利です。 。

注:このCSSスクロールは未加工であり、まだ解決されていない既知の問題がいくつかあることを警告したいと思います。上または下の境界を超えてスクロールするか、タッチする(移動しない)場合でもスクロールします。また、悪名高いURLバーは非表示になりません。ですから、やるべきことがあります。

2
ihor marusyk

スクロールイベントをウィンドウ、ドキュメント、本文ではなく、カスタムコンテナに添付する必要がありました。

IOSでは、これらのハードウェアアクセラレーションによるウィンドウスクロール動作中にプログラムで反応することはできません。

これがフィドルです:ラッパー:

<div id="content">

あまり関係のないCSS:

html,body,#content {
    width:100%;
    height:100%;
}
#content {
    background-color: lightblue;
    overflow:scroll;
}

リスナーをコンテナーにアタッチする:

function checkScrolling() {
    if ($('#content').scrollTop() > mastheadHeight) {
        menu.addClass('fixed');
    } else {
        menu.removeClass('fixed');
    }
}

$('#content').scroll(function () {
    checkScrolling();
});

ここでは、JSのみのフォールバックで機能していることがわかります。

http://jsfiddle.net/jaibuu/YqPzS/

直接URL: http://fiddle.jshell.net/jaibuu/YqPzS/show/

2
Jaibuu

関数の効率をテストしました。あなたはこれを試してみるべきです

function checkScrolling() {         
    if( $(window).scrollTop() > mastheadHeight )menu.css('position','fixed');
    else menu.css('position','');
}

これにより、addClassとRemoveClassの関数呼び出しが減り、実行時間が有効になります。より多くの実行時間を短縮したい場合は、純粋なJavaScriptを使用することをお勧めします

1
Wasim A.
$(document).ready(function(){
     var p = $("#stop").offset().top;

    $(window).scroll(function(){
        if(p<$(window).scrollTop()){
            console.log("div reached");
            $("#stop").css({position:"fixed",top:0});
        }
        else{
            console.log("div out");
            $("#stop").css({position:"static"});
        }

    })
});

これはあなたを助けると思います。

合計コードは ここ jsfiddle.netにあります。

オンラインipad2シミュレータのサファリを使用したipad in http://alexw.me/ipad2/ でテストし、そこで動作しました。だから、私はそれが実際のiPadでも動作すると思います。

1
Ramsharan
setScrollTop: function(inTop) {
    var top = Math.max(0,inTop);

    if (wm.isMobile) { // should always be true for touch events 
        top = Math.min(top, this.listNode.clientHeight - this.listNodeWrapper.clientHeight);

        if (dojo.isWebKit) {
            this.listNode.style.WebkitTransform = "translate(0,-" + top + "px)";
        } else if (dojo.isMoz) {
            this.listNode.style.MozTransform = "translate(0,-" + top + "px)";
        } else if (dojo.isOpera) {
            this.listNode.style.OTransform = "translate(0,-" + top + "px)";
        } else if (dojo.isIE) {
            this.listNode.style.MsTransform = "translate(0,-" + top + "px)";
        }
        this.listNode.style.transform = "translate(0,-" + top + "px)";
        this._scrollTop = top;
        this._onScroll();
    } else {
        this.listNode.scrollTop = top + "px";
    }
},
1
krishna singh

これを起動するためにタッチイベントが必要ですか?最新のデバイスは、$(window).scroll()イベントとscrollTop値を返す必要があります。古いAndroidおよび以前のios5(私は思う)では、position:fixed:ビューポートがどのように機能したかにより、期待どおりに機能しませんでした。ただし、すべての新しいリリースで修正されています。

デバイスをさらにデバッグするには、Adobe EdgeInspectを強くお勧めします。あなたは出来る console.log scrollTopを使用して、気になるデバイスが実際に正しく動作するかどうかを確認します。あなたは彼らの無料版であなたが必要とするすべてを手に入れるでしょう。

1
Jason Lydon

スクロールイベントを処理するための優れた方法は、チェックをスクロールイベントに添付しないことです。多くのリソースが必要であり、古いブラウザではうまく機能しません。幸い、タイムループを実行するだけで、より多くの制御を行うことができます。コード的には次のようになります:(Twitterで使用されています)

var MyMenu = $('#menu'),
    didScroll = false;

$(window).scroll(function() {
    didScroll = true;
});

setInterval(function() {
    if ( didScroll ) {
        didScroll = false;
        //Do your check here
        checkScrolling();
    }
}, 180);

この種の操作は多くのリソースを必要とし、常にjqueryに「要素を選択」して計算するように要求するため、$( '。masthead')。height()をこのcheckScrolling関数の外に(より高いスコープで)配置する必要があります。サイズは最終的にアプリケーションを遅くします:

  var headerHeight = $('.masthead').height()
  function checkScrolling()
  .....

最後に、interval属性の値を変更できます(現在は180(60hzより少し大きい-。画面の更新時間)です)。アプリのパフォーマンスを少し高めたい場合は、この値を大きくすることができます。精度が低い)

John ResigとTwitterに感謝します: http://ejohn.org/blog/learning-from-Twitter/

それがAjiosを助けたことを願っています!

1
Abdoul Sy