Loading more items from database ~ Infinite Scroll

2019-03-22 05:08发布

问题:

I am new to ajax/php so am trying to figure out the best way of doing this.

I have got a sql database fill of 1500 items that I am loading into my page. I want to load 30 items into the page then when the user gets to the bottom of the web page I want it to then load another 30 items.

So far I have the 30 items displaying on my webpage, with a drop down menu that filters the items. I also have a function that fires when the user gets to the bottom of the page.

Can anyone help me with the PHP script to make this work and load more items? The code I am using is below.

Thanks

HTML

<section id="filters">
    <select name="entries"  onchange="filterEntries()">
        <option value="*">show all</option>
        <option value=".item323">323</option>
        <option value=".item266">266</option>
        <option value=".item277">277</option>
        <option value=".item289">289</option>
    </select>
</section> <!-- #filters -->

<div id="entries" class="clearfix">
    <div class="ajaxloader"><img src="<?php bloginfo('template_url'); ?>/ajax_load.gif" alt="loading..." /></div><!--ajaxloader-->
</div><!--entries-->
<div class="ajaxloader"><img src="<?php bloginfo('template_url'); ?>/ajax_load.gif" alt="loading..." /></div><!--ajaxloader-->

Jquery

$(document).ready(function () {
    loadData();
    //Hide Loader for Infinite Scroll
    $('div.ajaxloader').hide();

});

function loadData () {
//Show Loader for main content
    $('#entries .ajaxloader').show();
//Pull in data from database
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        "use strict";
        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("entries").innerHTML=xmlhttp.responseText;
        //Fire filter function once data loaded
            filterEntries();
            //Hide Loader for main content once loaded
            $('#entries .ajaxloader').hide();
    }
    }
    xmlhttp.open("POST","<?php bloginfo('template_url'); ?>/getentries.php?$number",true);
    xmlhttp.send();
};


//Isotope filter
function filterEntries () {
    var $container = $('#entries');
       $select = $('#filters select');

    $container.isotope({
        itemSelector : '.item'
    });

    $select.change(function() {
    var filters = $(this).val();

    $container.isotope({
            filter: filters
    });
});
};

$(window).scroll(function () {
    if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
    $('div.ajaxloader').show('slow');

        //alert("Function to load more entries");

    }
});

PHP

<?php
    //Connect to Database
    $con = mysql_connect("localhost", "root", "root");
    if (!$con) {
        die('Could not connect: ' . mysql_error());
    }
    mysql_select_db("awards", $con);


    $sql="SELECT * FROM entry WHERE  status = 'registered' ORDER BY `entry_id` LIMIT 0, 30";

    $result = mysql_query($sql);


    while($row = mysql_fetch_array($result)) {
        //Get award cat ids
        $awardcat =  $row['awards_subcategory_id']  ;

        print "<div class='item item$awardcat clearfix'>";//add award cat id to each div
        print '<img class="image" src="http://localhost:8888/awardsite/wp-content/themes/award/placeholder.jpg" />';
        print "<p > Studio: " . $row['studio'] . "</p>";
        print "<p class='client'> Client: " . $row['client'] . "</p>";
        print "<p class='description'> Description: " . $row['description'] . "</p>";
        print "<p class='solutionprocess'> Solution Process: " . $row['solution_process'] . "</p>";
        print "</div>";

    }





    mysql_close($con);
?> 

回答1:

This is quite a complex question. Before trying to code your own variation from scratch, I suggest you take a look at the Infinite Scroll jQuery Plugin. If that doesn't fix it, here's a possible solution:

Javascript

$(document).ready(function () {
    loadData( 0 );
    //Hide Loader for Infinite Scroll
    $('div.ajaxloader').hide();

});

function loadData ( last_id ) {
    var $entries = $('#entries'),
        $loader = $('.ajaxloader', $entries).show();
    $.get( '/getentries.php', { last_id : last_id }, function( data ) {
        $entries.append( data ).append( $loader.hide() );
        filterEntries();
    });
};


//Isotope filter - no changes to this code so I didn't include it

$(window).scroll(function () {
    if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
        $('div.ajaxloader').show('slow');
        loadData( $( '#entries item:last' ).data('id') )
    }
});

PHP

<?php
//Connect to Database
$con = new mysqli( 'localhost', 'root', 'root', 'awards' );
if( $con->connect_errno ) {
    die( 'Could not connect:' . $con->connect_error );
}

$last_id = isset( $_GET['last_id'] ) ? (int)$_GET['last_id'] : 0; 
$stmt = $con->prepare( 'SELECT * FROM entry WHERE status = "registered" AND entry_id > (?) ORDER BY entry_id LIMIT 0, 30' );
$stmt->bind_param( 'i', $last_id );
$stmt->execute();

$result = $stmt->get_result();    
while( $row = $result->fetch_assoc() ) {
    //Get award cat ids
    $awardcat = $row['awards_subcategory_id'];

    print "<div class='item item$awardcat clearfix' data-id='" . $row['entry_id'] . "'>";//add award cat id to each div
    print '<img class="image" src="http://localhost:8888/awardsite/wp-content/themes/award/placeholder.jpg" />';
    print "<p > Studio: " . $row['studio'] . "</p>";
    print "<p class='client'> Client: " . $row['client'] . "</p>";
    print "<p class='description'> Description: " . $row['description'] . "</p>";
    print "<p class='solutionprocess'> Solution Process: " . $row['solution_process'] . "</p>";
    print "</div>";

}
$con->close();

The Javascript code sends an AJAX GET request to the php script with the id of the last entry displayed in the list. The PHP script then returns 30 entries that come after that id. The original Javascript file had a bit of PHP code in it. I removed that, as I don't know what its purpose is (are you outputting the JS from a PHP script maybe?). Also, the whole XMLHttpRequest code can be shortened to the $.get() function. You're using jQuery anyway, so you don't need to reinvent the wheel. I used the data-id attribute to transmit the entry ids. That is a HTML5 specific attribute. If you don't want to use it, just use id instead, but remember that ids cannot start with a number - you should prefix it with a letter.

In the PHP script, I used mysqli instead of the mysql_* functions. You should use mysqli or PDO from now on, as they are more reliable and secure than the (now deprecated) mysql_*. Your PHP installation most likely includes these extensions already. Note that I didn't handle database querying errors. You can write that code yourself. If you get other kinds of errors, post them here and I will try to fix them.