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 呼び出しを 1 回行うスクリプトの仕事になりました。この間に複数の 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が大量のスクロールイベントを発生させるという同様の問題がありましたが、クロムはそうではありませんでした。

私がしたことは、(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 に答える