用jQuery Mobile调用AJAX - 为什么方法被调用两次?

时间:2013-02-28 13:54:00

标签: jquery jquery-mobile

我正在撕掉我的头发。我是jQuery Mobile的新手,我有一个功能,只要浏览器滚动到页面底部,就会加载新内容。

我还有一个<select>,您可以在其中选择类别。它在起始页面上工作正常(即没有选择类别时)。但是只要我选择一个类别,然后滚动到底部,函数bindScroll()就会触发两次。

我一直在努力寻找一些解决方案近两天,但没有。我还没有真正弄清楚不同的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的建议,没有绑定并重新绑定滚动事件。页面初始化时只有一个绑定。 然后我使用了这段代码:

// 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;

                }
            }
        }
    }

并将scrollHappening = false设置为ajax调用的success:。似乎工作得很好!

1 个答案:

答案 0 :(得分:0)

在选择类别后重新绑定此位置的bindScroll,因此它会被调用两次!?即当您选择一个类别时,您可以调用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个事件,因此滚动 - &gt; bindscroll == 1 event bound
  2. LoadAdds()您现在绑定了2个事件     所以滚动 - &gt; bindscroll == 2个绑定的事件
  3. 当你实际滚动时,如果你有2个绑定到bindscroll的事件,那么在unbind发生之前它会调用这两个事件是我猜的。

    我认为你真正的解决方案是不要一直绑定和取消绑定。绑定一次,不要使用bind / unbind玩这个游戏。更改代码以使用单个绑定。在底部,有一个变量来标记你是否已经在底部,如果你已经退出该功能。或类似的东西。您通过此绑定/解除绑定业务为自己制造了一个令人头疼的问题。