Load content only when scrolled – AJAX, Javascript, PHP & MySQL

In this tutorial, we are going to teach you how you can load the content of div only when user scrolled to that section. For example, you have a lot of dynamic sections in your website, loading them all using PHP is very costly since server has to get a lot of data from database and it will make your website load slower. Second option was to load all data using AJAX, this will solve the first problem because the website will be loaded instantly and all the sections where dynamic data needs to be displayed will send an AJAX request to get that data and display in relevant section using Javascript.

However, take this example, if your website has 10 sections and users mostly use the first 3 sections. This means that the server is serving 7 extra requests which are not commonly being used by client. It will slowdown the server, possibly crash your website if you have a lot of users. What if we find a way of optimization such that the relevant section will only be loaded when required by user. Simply means, request of section will be sent to server only when asked by client to get that data. If user is on first 3 sections, then the ajax will be called only 3 times and server will be serving only 3 requests. Request for section 4 will only be served if user moved or scrolled to that section, otherwise it will not be loaded. It will greatly optimize your website and make it load faster and more responsive.

This tutorial is written in pure Javascript, no jQuery or any other external library has been used. So you can use this tutorial under all Javascript and PHP frameworks.

We have created a sample database called “classicmodels” from where we are going to load the data from 4 tables:

  1. customers
  2. employees
  3. offices
  4. products

The important question here is “How am I going to know when user has scrolled to some div ? And how can I tell the server to get data required in that div ? And how to display it in relevant div ?”. For this, we are going to use Javascript built-in IntersectionObserver object, basically it observes all the nodes in the intersection. Intersection is a visible area in browser, when you open any website, the content which is visible to you is in Intersection. So we are going to add all divs which needs to be loaded dynamically under observation. Once that div intersects, we are going to send a simple AJAX request using Javascript (no jQuery), telling the server what type of data we need and then display the data in that div.

Server side (PHP)

Paste the following code in your server side or back-end PHP file, we have named it “Http.php“. Make sure to change the database credentials.

<?php
	// File name = Http.php

	// Get data from database

	if (isset($_GET["type"]))
	{
		// Connecting with database
		$conn = mysqli_connect("localhost", "root", "", "classicmodels");

		// Just for testing, set a delay for 2 seconds
		sleep(2);

		// Getting all results from relevant table
		// you can perform different queries for each div using $_GET['type'] variable

		$type = $_GET["type"];

		$result = mysqli_query($conn, "SELECT * FROM " . $type);
		$data = array();

		while ($row = mysqli_fetch_object($result))
		{
			array_push($data, $row);
		}

		// Sending response back
		// we also need to send the type back
		echo json_encode(array(
			"data" => $data,
			"type" => $type
		));
		exit();
	}
?>

Client side

Paste the following code in your client side or front-end. Make sure to change the IDs of divs as per your project. Also set server file name as per yours at line 13.

<!-- Create divs which needs to be loaded by ajax -->
<div id="customers" class="loaded-by-ajax"></div>

<div id="employees" class="loaded-by-ajax"></div>

<div id="offices" class="loaded-by-ajax"></div>

<div id="products" class="loaded-by-ajax"></div>
<script>
	// Create observer
	var ajaxObserver = new IntersectionObserver(function (items, self) {
		// Loop through all items in visible area
		for (var a = 0; a < items.length; a++) {
			// Check if div under observation is in visiable area
			if (items[a].isIntersecting) {
				// Get ID
				var id = items[a].target.id;
				
				// Call ajax to get data
				var ajax = new XMLHttpRequest();
				ajax.open("GET", "Http.php?type=" + id, true);

				// Show loading in relevant div before ajax
				document.getElementById(id).innerHTML = "Loading..." + id;

				// This event will be called for each request change status
				ajax.onreadystatechange = function () {
					// Response is received when ready state is 4 and status is 200
					if (this.readyState == 4 && this.status == 200) {
						// Convert JSON string into arrays and objects
						var response = JSON.parse(this.responseText);

						var data = response.data;
						var type = response.type;

						var html = "";
						// Each div might have different layout

						if (type == "customers") {
							html += "<h1>Customers</h1>";

							// Loop through all items
							for (var b = 0; b < data.length; b++) {
								html += "<p>" + data[b].customerName + "</p>";
							}
						} else if (type == "employees") {
							html += "<h1>employees</h1>";

							// Loop through all items
							for (var b = 0; b < data.length; b++) {
								html += "<p>" + data[b].firstName + " " + data[b].lastName + "</p>";
							}
						} else if (type == "offices") {
							html += "<h1>offices</h1>";

							// Loop through all items
							for (var b = 0; b < data.length; b++) {
								html += "<p>" + data[b].city + "</p>";
							}
						} else if (type == "products") {
							html += "<h1>products</h1>";

							// Loop through all items
							for (var b = 0; b < data.length; b++) {
								html += "<p>" + data[b].productName + "</p>";
							}
						}

						// Render the relevant div
						document.getElementById(type).innerHTML = html;
					}
				};

				// Sending the ajax request
				ajax.send();

				// Prevent the div from being observed again
				self.unobserve(items[a].target);
			}
		}
	});

	// Add all loaded-by-ajax divs in observation list
	var loadedByAjax = document.getElementsByClassName("loaded-by-ajax");
	for (var a = 0; a < loadedByAjax.length; a++) {
		ajaxObserver.observe(loadedByAjax[a]);
	}
</script>

Leave a Reply

Please disable your adblocker or whitelist this site!