MySQL, AJAX – weitere Datensätze beim scrollen nachladen

Ich habe einige Mitteilungen bekommen, dass diese Version meines Tipps nicht unter allen Browsern funktioniert.
Dies habe ich zum Anlass genommen, eine neue version zu veröffentlichen. Diese finden Sie hier

Mit Ajax kann man schon tolle Sachen machen. So ist es z.B. möglich, weitere Datensätze aus einer MySQL-Datenbank, automatisch nachzuladen wenn man die Seite nach unten scrollt ohne dass dabei die Seite selbst neu geladen werden muss. Auf der Google+ Seite sieht man ganz schön was gemeint ist.

Die für dieses Beispiel benötigte Datei jquery-1.7.1.js kann man unter http://code.jquery.com/jquery-1.7.1.js herunter laden.

Außerdem brauchen wir für dieses Beispiel noch eine MySQL-Datenbank, aus der wir beim starten der Seite die ersten 5 Einträge laden. Wenn man anschließend zum letzten Eintrag nach unten scrollt, werden automatisch die nächsten 5 Einträge aus der Datenbank in die Liste geladen.

 

MySQL-Datenbank

id = bigint(11) AutoIncrement
Vorname = varchar(50)
Nachname = varchar(50)

Die fertige Datenbankdatei kann hier heruntergeladen und in die eigene Datenbank importiert werden.

 

index.php

<?php include("includes/database.inc.php"); ?>

<html>
 <head>
  <title></title>
  <script type="text/javascript" src="assets/scroll/jquery-1.7.1.js"></script>
  <script type="text/javascript">
  $(function()
  {
    var killScroll = false;
    $(window).scroll(function()
    {
      if ($(window).scrollTop()+200 >= ($(document).height() - ($(window).height())))
      {
        if (killScroll == false) 
        { 
          killScroll = true;

          $("#loader").show();

          var id = $("#block ul li:last").attr("id");
          $.ajax({
          type: "post",
          url: "assets/scroll/scroll.php",
          data: {"id":id},
          success: function(veri)
          {
            if(veri == 'letzter')
            {
              $("#loader").html("Keine Datensätze mehr vorhanden!");
            }
            else
            {
              $("#block ul").append(veri);
              $("#loader").hide();
              killScroll = false;
            }
          }
        });
      }
    }
  });
});
</script>  

<style type="text/css">
body
{
  margin: auto;
  font: 12px/21px Arial;
}

#block
{
  width: 350px;
  height: 500px;
  position: fixed;
  top: 0;
  right: 0;
  background-color: #f1f1f1;
  border: 1px solid #ccc;
  overflow: auto;
}

#block ul li
{
  padding: 10px;
  border-bottom: 1px solid #ddd;
  list-style: none;
}

#loader
{
  background-color: #fff;
  border: 1px solid #ccc;
  margin: 10px;
  padding: 8px;
  text-align: center;
  display: none;
}
</style>
</head>

<body>

<div id="block">
  <ul>
<?php
  $q_data = mysql_query("SELECT id, CONCAT(Nachname,' ',Vorname) AS Kunde FROM Kunden ORDER BY id ASC LIMIT 10");
  while($r_data = mysql_fetch_array($q_data))
  {
    echo '<li id="'.$r_data['id'].'">('.$r_data['id'].') '.$r_data['Kunde'].'</li>';
  }
?>
  </ul>
  <div id="loader"><img src="images/ajax-loader.gif" /></div>
</div> 

</body>
</html>

 

assets/scroll/scroll.php

<?php
require_once("../../includes/database.inc.php");

if(isset($_POST['id']) && $_POST['id'] != 0)
{
  $id = $_POST['id'];

  $q_data2 = mysql_query("SELECT id, CONCAT(Nachname,' ',Vorname) AS Kunde FROM Kunden WHERE id > ".$id." ORDER BY id ASC LIMIT 10");
  $n_data2 = mysql_num_rows($q_data2);
  if($n_data2 > 0)
  {
    while($r_data2 = mysql_fetch_array($q_data2))
    {
      echo '<li id="'.$r_data2['id'].'">('.$r_data2['id'].') '.$r_data2['Kunde'].'</li>';
    }
    sleep(1);
  }
  else
  {
    echo 'letzter';
  }
}
?>

 

includes/database.inc.php

<?php 
  if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) exit('No direct access allowed.');

  $hostname = "localhost";
  $username = "root";
  $password = "MeinPasswort";
  $dbname   = "Datenbankname";
  $char_set = "utf8";

  $conn = mysql_connect($hostname, $username, $password) or die(mysql_error());
  mysql_select_db($dbname, $conn) or die(mysql_error());
?>

Bitte beachten Sie, dass Sie auf jeden Fall die Datenbank mit genügend Einträgen anlegen und dass Sie in der Datei „includes/database.inc.php“ die Zugangsdaten zu Ihrer Datenbank anpassen müssen.

  • Das komplette Projekt kann hier heruntergeladen werden.
  • Eine SQL-Datei zum Import einiger Datensätze in die MySQL-Datenbank können Sie hier herunter laden.

Über Enrico S.

Programmierer, Webdesigner, Grafiker, Blogger, Screencaster, Arduino- und eMobility Enthusiast.

23 Kommentare zu “MySQL, AJAX – weitere Datensätze beim scrollen nachladen

  1. Hey kannst du bitte ein Beispielprojekt hochladen ?
    Bei mir scheint es nämlich nicht zu klappen ansonsten eine sehr schöne Idee :)
    Gruß Jan

    • Habe mir den Code gerade noch mal angeschaut.
      Das is doch ein komplettes Projekt. Du müsst halt die Datenbank anlegen, den Zugang zur Datenbank anpassen und dann sollte auch passen.

      Wo hackt es denn bei dir?

  2. er lädt keine neuen Datensätzte, die Datenbank etc wurde angelegt er zeigt diese auch an nur wenn man scrollt kommen einfach keine neuen Daten. Bei der prüfung „if($(this).scrollTop() === $(„.block“).height() – $(this).height())“ kommt auch immer ein false raus.

  3. So, ich habe den Beitrag noch mal komplett überarbeitet und auch die Datenbankdatei zum testen und das komplette Projekt hinzugefügt.

    Sag mir bitte bescheid wenn noch Unklarheiten bestehen.

    • Anscheinend funktioniert es jetzt :), Danke.
      Aber nur wenn ich die Daten nicht in dem Block div lade.

  4. Hallo,
    ich würde das ganze gern mit Div Containern machen!Wie muss ich das Script abändern?

    THELokusta

  5. Also ich habe es mir noch einmal angeschaut. Ich denke Du hast das Beispiel als Zip von dieser Website heruntergeladen. Schau mal in der Datei index.php und entferne die letzten 7 Zeilen ganz unten über < /body>.


    < ?php $q_data = mysql_query("SELECT id, Nachname, Vorname FROM Kunden ORDER BY id ASC"); while($r_data = mysql_fetch_array($q_data)) { echo "INSERT INTO `kunden` (`id`, `Nachname`, `Vorname`) VALUES(".$r_data['id'].", '".$r_data['Nachname']."', '".$r_data['Vorname']."');
    ";
    }
    ?>

    Also nicht die im < div id="block"> sondern die darunter. Das hatte ich nur zum testen da stehen und es vergessen zu löschen.

    Deine Frage sollte sich dann auch erübrigt haben. Die Daten werden nämlich in einem div layer angezeigt.

    Also wenn Du z.B. willst dass Dein Div-Layer in dem die Beiträge nachgeladen werden sollen, über die komplette Seitenhöhe geht dann ändere einfach den css Teil wie folgt.

    #block
    {
    width:250px; /* NEU */
    height: 100%; /* NEU */
    margin:auto 0 auto 0; /* NEU */
    position: fixed;
    top: 0;
    right: 0;
    background-color: #f1f1f1;
    border: 1px solid #ccc;
    overflow: auto;
    }

  6. Funktioniert ganz gut, nur wird der letzte Beitrag (Wenn keine mehr vorhanden sind) 2-3-4 fach (immer unterschiedlich) nochmal ganz am ende geladen.

    Und der Nachteil ist das es bei Mobilengeräten nicht funktioniert.

  7. ich habe das ganze Script mal getestet, es zeigt mir zwar 10 Beiträge an, aber beim Scrollen nach ganz unten werden keine neuen Beiträge geladen… :( (bitte um Antwort) ist zu 1:1 übernommen.

    • Hallo, ich habe das ganze Script jetzt noch einmal aufgetzt, habe dabei die .js ausgetauscht, aber leider der selbe Fehler. Ich kann mir vorstellen, das die “assets/scroll/scroll.php“ ein fehler hat, weil wenn ich “localhost/assets/scroll/scroll.php“ eintrage in die URL seh ich eine leere Zeile.

    • Der Code funktioniert auf jeden Fall, ich habe ihn selber eben noch mal getestet.
      Wenn Du die js-Datei direkt im Browser aufrufst und wenn Du Dir sicher bist dass der angegebene Pfad stimmt, dann solltest Du mal die Zugriffsrecht der Datei mit chmod prüfen.

  8. bei mir funktioniert es wunderbar. Allerdings kann ich das DIV mit dem „Loader“ nicht einbinden. Wenn ich ihn einbinde, dann erscheinen die letzten Einträge immer doppelt. Entferne ich ihn wieder, funktioniert es wunderbar… Woran kann das liegen? Ich nehme an, am Selector oder?

  9. Ok, habe gerade gesehen, wenn ich langsam scrolle klappt es. Aber ich kann dem User ja kein Schild vorsetzen: BITTE LANGSAM SCROLLEN ;) Gibt es dafür eine Lösung?

    • Hallo Oliver, entferne mal das sleep(1); aus der Datei scroll.php!
      Ich muss das noch mal überarbeiten. Wenn Du das sleep(1); entfernst werden die Datensätze nicht mehr durcheinander oder doppelt geladen, dafür wird aber auch das Lade-Image nicht gezeigt.

  10. Ich habe das Script nochmals überarbeitet. Das doppelte oder unsortierte laden neuer Beiträge aus der Datenbank bei schnellem scrollen wird nun unterbunden.