1

私はこれで髪を引き裂いています。私はjQuery Mobileが初めてで、ブラウザがページの一番下までスクロールするたびに新しいコンテンツをロードする機能を持っています。

また、<select>カテゴリを選択できる場所もあります。開始ページ (つまり、カテゴリが選択されていない場合) で問題なく動作します。しかし、カテゴリを選択して一番下までスクロールするとすぐに、関数bindScroll()が 2 回トリガーされます。

解決策を見つけようとほぼ2日間これに取り組んできましたが、何もありませんでした。jQuery Mobile のさまざまなイベントについてはまだよくわかっていないため、問題がある可能性があります。

私のコードを見て、できれば助けてください。このサイトは .NET MVC で構築されていますが、問題は jQuery にあります。

@using Namespace.Helpers
@{
    ViewBag.Title = "Home Page";
}
<!-- Get a drop down of the different categories -->
@Html.Raw(Html.GetCategories(true, "CategoryId", 0, true))

<!-- list view to append the fetched ads to -->
<ul data-role="listview" data-inset="true" id="ad-list">

</ul>

<script>
    // keeps track of how many rows to skip in the db. this is passed along to the server side
    var currentPos = 0;

    // save the categoryId
    var categoryId = $('#CategoryId').val();

    $('#page-start').live('pagecreate', function () {

        // load the ads for the first call
        loadAds();


        //handle the category drop down
        $('#CategoryId').change(function () {
            // clear the list of ads
            $('#ad-list').empty();

            // reset so we start fetching from the first row in the db, used on server side
            currentPos = 0;

            // update the category value to pass along to the server
            categoryId = $('#CategoryId').val();

            // just to know that it has a value
            console.log(categoryId);

            // re-load the new ads
            loadAds();

        });


    });

    // method that loads ads via AJAX
    function loadAds() {
        console.log('loadAds()');
        $.ajax({
            // method on the server that returns a partial view
            url: '/Home/LoadMoreAds',
            type: 'GET',
            data: {
                // pass along some data
                currentPosition: currentPos,
                categoryId: categoryId
            },
            success: function (result) {
                // add the result to the ad-list
                $('#ad-list').append(result);
                $('#ad-list').listview('refresh');

                // once again, bind the scroll event
                $(window).scroll(bindScroll);

            },
            error: function (data, textStatus, jqXHR) {
                alert(textStatus);
            }

        });

    }

    // method that checks if the scroll is near the bottom of the page
    function bindScroll() {
        if($(document).height() > $(window).height())
        {
            if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
                $(window).unbind('scroll');

                // just to know that the method has run
                console.log('bindScroll()');

                // update counter to skip the already loaded rows
                currentPos++;

                // load new ads
                loadAds();

            }
        }
    }

</script>

編集された回答: -----------------------------------------------

スクロール イベントをバインドおよび再バインドしないように、Mike C からの提案を受けました。ページ初期化時のバインドは 1 つだけです。そして、私はこのコードを使用しました:

// method that checks if the scroll is near the bottom of the page
    var scrollHappening = false;
    function bindScroll() {
        if (scrollHappening) {
            return false;
        } else {
            if ($(document).height() > $(window).height()) {
                if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {

                    // just to know that the method has run
                    console.log('bindScroll()');

                    // update counter to skip the already loaded rows
                    currentPos++;

                    // load new ads
                    loadAds();

                    scrollHappening = true;

                }
            }
        }
    }

そしてajax 呼び出しの に を設定scrollHappening = falseします。success:かなりうまくいくようです!

4

1 に答える 1

0

カテゴリを選択した後、この場所で bindScroll を再バインドするため、2 回呼び出されます!? つまり、カテゴリを選択するときは、次のような LoadAds() を呼び出します。

success: function (result) {
                    // add the result to the ad-list
                    $('#ad-list').append(result);
                    $('#ad-list').listview('refresh');

                    // once again, bind the scroll event
                    $(window).scroll(bindScroll);

                },

LoadAdds() を呼び出すたびに、この関数は bindscroll を呼び出すためのイベントを追加します。

  1. LoadAdds() スクロールに 1 つのイベントがバインドされているため、スクロール --> bindscroll == 1 つのイベントがバインドされます。
  2. LoadAdds() これで 2 つのイベントがバインドされたので、スクロール --> bindscroll == 2 つのイベントがバインドされます。

実際にスクロールすると、bindscroll に 2 つのイベントがバインドされている場合、バインド解除が発生する前に両方のイベントが呼び出されると思います。

ここでのあなたの本当の解決策は、常にバインドしたり解除したりしないことだと思います。1回バインドし、バインド/アンバインドでこのゲームをプレイしないでください。コードを変更して、単一のバインドで動作するようにします。一番下に、すでに一番下にいる場合はマークする変数があり、そうである場合は関数を終了します。または似たようなもの。このバインド/バインド解除ビジネスで、自分自身の頭痛の種を作成しています。

于 2013-02-28T14:01:48.670 に答える