6

我使用 3 个不同的函数通过 AJAX 将数据加载到我的 DIV 中。当浏览器滚动条保持在我延迟加载数据的 DIV 底部时,我试图阻止多个 AJAX 调用。

这可行,但有时(只是有时)滚动条仍位于我的 div 的底部,这将导致发生许多 AJAX 调用。我该如何防止这种情况发生?

$(document).ready(function() {

    //form submit by click
    $("#submit").click(function(e) {
        // Prevent Default Action In Case to Load data by form
        e.preventDefault();

        //prevent select to post empty data
        $('select').each(function() {
            if ($(this).val() == '') {
                $(this).attr('disabled', 'disabled');
            }
        });

        // Define what we need
        var loading = "<img src='/zojfa/images/loading.gif' alt='Loading...' />";
        var scrolltop = $('#scrollbox').attr('scrollTop');
        var scrollheight = $('#scrollbox').attr('scrollHeight');
        var windowheight = $('#scrollbox').attr('clientHeight');
        var post = $(this).attr("name") + "=" + $(this).val();
        var form_data = $('#search_form').serialize() + "&" + post;
        var scrolloffset = 20;

        //empty content if another value sent to code
        $('#content').empty();
        //load data
        loaddata(form_data, 0);
    });

    //listen to scroll function
    $('#scrollbox').scroll(function() {

        //define what we need
        var scrolltop = $('#scrollbox').attr('scrollTop');
        var scrollheight = $('#scrollbox').attr('scrollHeight');
        var windowheight = $('#scrollbox').attr('clientHeight');
        var scrolloffset = 20;

        //get number of div which will append to script in case of limit database to page 2 or 3 or...
        size = $('#content > div').children().size();



        //if we reach to bottom of div we are going to call to ajax function
        if (scrolltop >= (scrollheight - (windowheight + scrolloffset))) {
            var form_data = $('#formdata').val();

            //if remain of size(count of div) is 0 then we have more data to show because we limit data provided by script to 7 field(we handle situation that we had 14 or 21 respond from database in "next step" because if there is no data to show we dont have to let script to run)
            if (size % 7 == 0) {
                //call to load data function
                setTimeout(function() { loaddata(form_data, size) }, 1500);
            } else {
                //do nothing its just in case we need to append something like no more data to load
            }
        }
    });

    // page load finish
});


//function to load data
function loaddata(form_data, size) {
    number = "&size=" + size;
    //fetch new items
    $.post('dosearch.php', form_data + number, function(newitems) {
        //next step : if page echoing "" then do nothing
        if (newitems == '') {} else {
            //if we have data append these data to our div's #content
            $('#content').append(newitems);
        }
    });
}​

更新

我按照亲爱的@Kent Pawar和亲爱的@E.J. Brennan说的做了,但是现在当我到达 div 的底部时,我收到了更多的 AJAX 调用,但它仍然不能正常工作。

$("#submit").click(function(e) {
    // Do some Default
    e.preventDefault();

    $('select').each(function() {
        if ($(this).val() == '') {
            $(this).attr('disabled', 'disabled');
        }
    });

    // var what we need
    var loading = "<img src='/zojfa/images/loading.gif' alt='Loading...' />";
    var scrolltop = $('#scrollbox').attr('scrollTop');
    var scrollheight = $('#scrollbox').attr('scrollHeight');
    var windowheight = $('#scrollbox').attr('clientHeight');
    var post = $(this).attr("name") + "=" + $(this).val();
    var form_data = $('#search_form').serialize() + "&" + post;
    var scrolloffset = 20;

    $('#content').empty();

    //load data
    loaddata(form_data, 0);
    $('select').each(function() {
        if ($(this).val() == '') {
            $(this).removeAttr('disabled');
        }
    });
});


$('#scrollbox').scroll(function() {
    //var what we need
    var scrolltop = $('#scrollbox').attr('scrollTop');
    var scrollheight = $('#scrollbox').attr('scrollHeight');
    var windowheight = $('#scrollbox').attr('clientHeight');
    var scrolloffset = 20;

    // when we reach
    size = $('#content > div').children().size();

    if ($('#scrollbox').data('ajaxready') === false)
        return;

    if (scrolltop >= (scrollheight - (windowheight + scrolloffset))) {
        $('#scrollbox').data('ajaxready', false);
        var form_data = $('#formdata').val();

        if (size % 7 == 0) {
            setTimeout(function() { loaddata(form_data, size) }, 1500);
        } else {

        }
    }
    $('#scrollbox').data('ajaxready', true);

    // page load finish
});

function loaddata(form_data, size) {
    number = "&size=" + size;
    //fetch new items
    $.post('dosearch.php', form_data + number, function(newitems) {
        if (newitems == '') {} else {
            $('#content').append(newitems);
        }
    });
}
4

2 回答 2

7

那么问题不在于滚动条位于页面底部,而在于事件处理程序的工作方式。有时滚动条会位于页面底部,例如当没有更多帖子要加载时……例如观察 Facebook 的墙。

目前,滚动发生时会触发JQuery滚动事件。

jQuery 文档:

无论原因如何,只要元素的滚动位置发生变化,就会发送滚动事件。在滚动条上单击或拖动鼠标、在元素内拖动、按箭头键或使用鼠标滚轮都可能导致此事件。

现在它的脚本的工作是进行单个 AJAX 调用以检查是否有要加载的内容。您需要修改您的脚本以阻止在此期间发生多个 AJAX 调用,正如我所见@E.J. Brennan,已经提出了相同的建议:)。

您可以按如下方式添加标志:

//listen to scroll function
  $('#scrollbox').scroll(function(){

        //[Kent] Before we service the event, we check if the last scroll event was handled/completed.
        //If it is not yet compelted, don't start another one and jump out of the code.
        if ($(window).data('ajax_in_progress') === true)
            return;

        //define what we need
        var scrolltop=$('#scrollbox').attr('scrollTop');
        var scrollheight=$('#scrollbox').attr('scrollHeight');
        var windowheight=$('#scrollbox').attr('clientHeight');
        var scrolloffset=20;

        //get number of div which will append to script in case of limit database to page 2 or 3 or...
        size =  $('#content > div').children().size();

        //if we reach to bottom of div we are going to call to ajax function
        if(scrolltop>=(scrollheight-(windowheight+scrolloffset))){
            $(window).data('ajax_in_progress', true);  //[Kent] prevent more scroll events as AJAX request will soon begin. 

            var form_data = $('#formdata').val();

            // if remain of size(count of div) is 0 then we have more data to show because 
            // we limit data provided by script to 7 field(we handle situation that we had 
            // 14 or 21 respond from database in "next step" because if there is no data to 
            // show we dont have to let script to run)
            if(size % 7 == 0){
                //call to load data function
                setTimeout(function(){loaddata(form_data, size)}, 1500);
            }else{
                //do nothing its just in case we need to append something like no more data to load
            }
        }
    });    



//function to load data
function loaddata(form_data, size){
    number = "&size=" + size;
    //fetch new items
    $.post('dosearch.php', form_data+number, function(newitems){
        // [Kent] This is the callback funciton that gets executed ONLY
        // when the AJAX request has completed. We will append the data
        // into the DOM and then reset the FLAG.

        //next step : if page echoing "" then do nothing
        if(newitems == ''){
        }else{
            //if we have data append these data to our div's #content
            $('#content').append(newitems).each(function() {
                //Adding a callback to append.
                // So we reset the flags here to indicate the scroll event 
                // has been handled/completed and so we turn scrolling events back on
                $(window).data('ajax_in_progress', false);
            });
        }
    });
}   
于 2012-12-09T15:54:58.597 回答
5

不是 100% 清楚你的确切问题,但我也遇到了类似的问题,即在第一个事件完成之前,Firefox 触发了大量滚动事件,而 chrome 没有。

我所做的是在开始(从 ajax)加载新数据时添加一个标志,并在完成时取消设置标志,这解决了我的问题。

像这样的东西:

    $(window).scroll(function () {

    //if last scroll is not done, don't start another one.
    if ($(window).data('ajaxready') === false)
        return;

    if ($(window).scrollTop() >= $(document).height() - $(window).height() - 100) {
        $(window).data('ajaxready', false);  //prevent more scroll events
        YourFunctionCallToGetGetMoreData();  //go get the data here.
    }

    //turn scrolling events back on
    $(window).data('ajaxready', true);
});

在您的情况下,将滚动返回的调用将进入 ajax 数据加载的回调函数。

于 2012-12-09T15:36:32.177 回答