AJAX 功能不能通过滚动工作

Posted

技术标签:

【中文标题】AJAX 功能不能通过滚动工作【英文标题】:AJAX function is not working by scroll 【发布时间】:2015-07-12 04:10:00 【问题描述】:

使用 AJAX 进行无限滚动。内容仅在第一次加载,但不会通过滚动加载。

怎么了?

jQuery:

function loadFeed() 
    $.ajax(
        url: 'loadmore.php',
        dataType: 'html',
        success: function (data) 
            $("#posts").append('<div class="havanagila"></div>');
            $('#posts').html(data);
        
    );


loadFeed();
$(window).scroll(function () 
    var windowScroll = $(window).scrollTop();
    var windowHeight = $(window).height();
    var documentHeight = $(document).height();

    if ((windowScroll + windowHeight) == documentHeight) 
        loadFeed();
    
);

加载更多.php:

<?php 
session_start();

if ( isset( $_SESSION['login'] ) ) 

    $login    = $_SESSION['login'];
    $id=$_SESSION['id'];

    $username="root";
    $password="root";
    $hostname = "localhost";
    $dbname= "kotik";


    function testdb_connect ($hostname, $username, $password)
        $dbh = new PDO("mysql:host=$hostname;dbname=kotik", $username, $password);
        return $dbh;
    


    try 
        $dbh = testdb_connect ($hostname, $username, $password);

     catch(PDOException $e) 
        echo $e->getMessage();
    



?>

<?php                                                              

$title_select_query= $dbh -> prepare("SELECT title FROM books WHERE id = :id ORDER BY date DESC");
$title_select_query ->execute(array(':id' => $id));
$title_select_query_result = $title_select_query->fetchColumn(); 
echo($title_select_query_result);

$title_select_query_result = $title_select_query->fetchColumn(); 
echo($title_select_query_result);

$title_select_query_result = $title_select_query->fetchColumn(); 
echo($title_select_query_result);

$title_select_query_result = $title_select_query->fetchColumn(); 
echo($title_select_query_result);

$title_select_query_result = $title_select_query->fetchColumn(); 
echo($title_select_query_result);

?>

【问题讨论】:

您在函数内部有一个事件处理程序,该函数在事件处理程序内部被调用。它只是不断增加。 什么不起作用?你检查过if ((windowScroll + windowHeight) == documentHeight) 这个条件是否真的有效吗? @VInand,你能添加预期的 html 结果吗? 请查看我的回答并回复 他在问为什么不将附加数据添加到 DOM 中。然后,他问为什么要加载相同的数据。我们认为他的 PHP 代码只是为 AJAX 调用提供了示例数据。有人给了他完整的可运行源代码,然后他选择了正确的答案。我永远不会欣赏这种答案,也永远不会支持这种不知道自己想要什么的人。 【参考方案1】:

因为你替换了 $('#posts') 的内容,所以在第一次 ajax 请求后,文档的高度在 scroll => 后没有改变,所以你需要向上滚动,然后再次向下滚动以触发另一个 ajax 请求。 因为不知道预期的页面布局,所以我将给出一个简单的基本演示 HTML JSFiddle demo

<div id="main" style="height:200px; overflow-y : auto;">
    <div id="posts">
    </div>
</div>

javascript

var loadmoore = true,
    loaded_posts =0 ;
function gent_sample_data(num_posts)
    var i,
        sample_data = '';
    for(i=0;i<num_posts;i++) 
        sample_data += "<p class'post'>title_select_query_result " + (loaded_posts + i) + "</p>"; 
    
    return sample_data;


function loadFeed()
     // generate sample data
    var sample_data = gent_sample_data(15);
    loaded_posts = loaded_posts + 15;
    $.ajax(
        url : '/echo/html/',
        dataType: 'html',
        type: 'post',
        data: 'html':sample_data,
        success: function(returnhtml)
            console.log(returnhtml);
             // option 1 - add result into "havanaglia" div
            // var $post = $('<div class="havanagila"></div>');
            // $post.html(returnhtml);
            // $("#posts").append($post);

            // option 2 - ad result after "havanaglia" div
            $("#posts").append('<div class="havanagila"></div>');
            $("#posts").append(returnhtml); 
            loadmoore = true;
            
    );

loadFeed();

$("#main").scroll(function ()  
    if (loadmoore && $("main").scrollTop() >= ($("main").height()-100) ) 
       loadmoore = false;
       loadFeed();
    
);

对于你的情况,我建议使用这样的东西:

var loadmoore= true;
function loadFeed() 
    $.ajax(
        url: 'loadmore.php',
        dataType: 'html',
        success: function (data) 
            var $havanaglia = $('<div class="havanagila"></div>');
            $havanaglia.html(data);
            $("#posts").append($havanaglia);
            loadmoore = true;
        
    );


loadFeed();

$(window).scroll(function ()  
    if (loadmoore && $(window).scrollTop() >= $(document).height() - $(window).height()-100) 
        loadmoore= false;
       loadFeed();
    
);

为了防止从数据库中获取相同的帖子,我建议将最后加载帖子的 id/number 发送到 php,以获取具有 id/number 的帖子 > 最后加载的帖子

【讨论】:

@vasilenicusor 它滚动,但它只是加载该数据两次,如 1 2 3 4 5 1 2 3 4 5 没错,第一次仅在页面加载时加载,第二次在您向下滚动时加载。因为文档的高度没有增加(您用新帖子替换现有帖子)。如果您不想保留现有帖子并加载数据超过两次,则在加载数据后,您必须将滚动位置更改为 0 或更改为 $(window).scrollTop() >= $(document ).height()-$(window).height()-100 为假。对您的代码的另一个修复是告诉 php 脚本您想要多少帖子以及从哪个位置例如SELECT title FROM books WHERE id= :id ORDER BY date DESC LIMIT 0,5【参考方案2】:

如果您想为每个滚动事件加载AJAX 函数,则无需检查if 条件。简单地写..

$(window).scroll(function()
        loadFeed();
);

如果你想在滚动到达底部时调用AJAX函数,你必须检查条件...

$(window).scroll(function()
    if ($(window).scrollTop() == $(document).height() - $(window).height())
        loadFeed();
    
);

【讨论】:

【参考方案3】:

把你的loadFeed()函数改成这个

function loadFeed() 
    $.ajax(
        url: 'loadmore.php',
        dataType: 'html',
        success: function (data) 
            $("#posts").append('<div class="havanagila"></div>');
            $('#posts').html($('#posts').html()+data);
        
    );

这是你必须做的改变$('#posts').html($('#posts').html()+data);

【讨论】:

@VarunHaharia 没有帮助。我建议问题部分出在 php 文件中。 如果您能够提供从中获取数据的数据库表,我相信我会在 30-40 分钟内为您提供解决方案,我只是不想先创建表并填写它用数据来测试代码【参考方案4】:

如果我没记错的话,我因类似的事情而遭受同样的问题。我所做的是停止滚动侦听器并在 AJAX 成功后重新启动它。

以下是可以帮助您的代码:

function loadFeed() 
    $.ajax(
        url: 'loadmore.php',
        dataType: 'html',
        success: function (data) 
            $("#posts").append('<div class="havanagila"></div>');
            $('#posts').html(data);
            $(window).on('scroll', function() checkScroll()); // Run the function again upon success
        
    );


var checkScroll = function() 
  if ($('#SomeElementAlwaysAtTheBottomOfThePage')[0]) 
    var el = $('#SomeElementAlwaysAtTheBottomOfThePage');
    var bottom_of_object = el.offset().top + el.outerHeight();
    var bottom_of_window = $(window).scrollTop() + $(window).height();

    if (bottom_of_window >= bottom_of_object)  // If we're at the bottom...
      $(window).unbind('scroll'); // Stop the scroll function
      loadFeed(); // Load the AJAX
    
  


$(window).on('scroll', function() checkScroll()); // Start the function off
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="posts"></div>
<div id="SomeElementAlwaysAtTheBottomOfThePage"></div>

【讨论】:

【参考方案5】:

看起来你用html()函数覆盖了元素#posts的内部内容。 $("#posts").append('<div class="havanagila"></div>'); $('#posts').html(data);

我想你想要 $("#posts").append($('&lt;div class="havanagila"&gt;&lt;/div&gt;').html(data));

关于您的 IF 语句 if ((windowScroll + windowHeight) == documentHeight),只有当您从页面的顶部滚动到底部(在 Chrome 上)时,才会调用您的 ajax 函数。

【讨论】:

【参考方案6】:

以下 javascript 代码用于在滚动条到达屏幕底部时加载 4 条记录。这意味着当第一次获取 4 条记录时,第二次获取下 4 条记录,这些记录将显示在屏幕上。此代码帮助我们减少页面加载时的加载延迟。

$(window).scroll(function() 
   if($(window).scrollTop() + $(window).height() == $(document).height()) 
       //alert("bottom!");
       loadNext();
   
);
var n1=0;
var n2=4;

function loadFirst()

    var n1=0;
    var n2=4;   

function loadNext()

    n1=n1+4;
    n2=n2+4;
    //alert(n1);    
    //alert(n2);
    if (window.XMLHttpRequest)
  // code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  
else
  // code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  
xmlhttp.onreadystatechange=function()
  
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    
    document.getElementById("testidiv").innerHTML=document.getElementById("testidiv").innerHTML+xmlhttp.responseText;
    
  
xmlhttp.open("GET","next_testimonial_action.php?a=" + n1 + "&b=" + n2,true);
xmlhttp.send();




</script>

"next_testimonial_action.php?a=" + n1 + "&b=" + n2" 是包含从db获取数据的逻辑的php页面,n1,n2是要获取的记录的限制。如果你需要您可以作为评论请求的 php 文件。谢谢

---- 重要---- "你必须在 bodyOnload 或 document.ready() jquery 中调用 loadFirst() 函数"

【讨论】:

【参考方案7】:

在我看来一切都很好,

只需将$(window).scroll(function () ...... 更改为

$(document).on( 'scroll','window', function()
              //or $(document).on( 'scroll','id of div containing scroll',
   var windowScroll = $(window).scrollTop();
   var windowHeight = $(window).height();
   var documentHeight = $(document).height();

    if ((windowScroll + windowHeight) == documentHeight) 
         loadFeed();
       
);

【讨论】:

【参考方案8】:

function loadFeed() 
    $.ajax(
        url: 'loadmore.php',
        dataType: 'html',
        success: function (data) 
            $("#posts").append('<div class="havanagila"></div>');
            $('#posts').html(data);
            $(window).on('scroll', function() checkScroll()); // Run the function again upon success
        
    );


var checkScroll = function() 
  if ($('#SomeElementAlwaysAtTheBottomOfThePage')[0]) 
    var el = $('#SomeElementAlwaysAtTheBottomOfThePage');
    var bottom_of_object = el.offset().top + el.outerHeight();
    var bottom_of_window = $(window).scrollTop() + $(window).height();

    if (bottom_of_window >= bottom_of_object)  // If we're at the bottom...
      $(window).unbind('scroll'); // Stop the scroll function
      loadFeed(); // Load the AJAX
    
  


$(window).on('scroll', function() checkScroll()); // Start the function off
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="posts"></div>
<div id="SomeElementAlwaysAtTheBottomOfThePage"></div>

【讨论】:

以上是关于AJAX 功能不能通过滚动工作的主要内容,如果未能解决你的问题,请参考以下文章

chartjs 从 ajax 加载数据不能正常工作

通过 AJAX 上传图片,不能在 jQuery 中使用 serialize() 方法?

粘性导航和滚动到顶部功能单独工作,但不能一起工作

能不能做一个html页面,然后按钮的功能用python实现

通过ajax获取一个多位数,当容器显示在屏幕可视区时,让数字以滚动的形式显示

Laravel使用无限滚动分页