jump to navigation

Create an Infinite Scroll Page Using Ajax-PHP and JQuery December 30, 2011

Posted by Tournas Dimitrios in JQuery.
trackback

By  combining  Ajax – PHP and JQuery’s functionality  we can create amazing web-applications . Today I’m going to demonstrate one more practical example , it emulates functionality that is  common nowadays on the most-visited  social-media websites ( Twitter , Facebook ) . Infinite scrolling , certainly this functionality is already well known to the majority of  web-surfers . Beside the eye – catching presentation , it serves a practical role . Imagine you had written an article a few months ago  that has gained lot of popularity  with respectively feedback from your visitors (for example 1000 comments ) , it would be impractical to display all these comments at-once on your web-page . A practical strategy is to display them in  chunks of 30 comments and  in reverse chronological order .  So , visitors will read the most resent comments first and if they are really  interested will scroll deep into  the bottom of  their browser to access older comments . Of course everything must be done behind the scene without the need to reload the page  .

Unfortunately my articles don’t have this popularity 🙂 , so I ‘ll emulate a similar scenario with Mysql’s  world database  ( download page ) . The “country” table of this database has 250 countries in its rows . I ‘ll  append (display)  30 countries at the bottom of the web-page each time the visitor “hits”  the bottom while  scrolling . A live demo can be seen on this page  and the complete source code .

Update : 11-08-2012 : A new version of the code is now  available on my GitHub repository . You should still read this article (and the comments) , as it provide the general concepts how the code works . The new code was  re-factored so that it can be used on live applications , but also a bug for IE8+ was fixed  . Fork me on GitHub or download  a zipped file of the new code  . Although the “old” code is still available , use it only on development environments as it’s not secure for production . This is a project in progress , based on  reader’s feedback the improvements will be “branched” on GitHub .
Update : 02-09-2012 : A new version (V0.4) is released on GitHub . For detailed description , visit GitHub and read README.md

I made  slightly modifications to Mysql’s world database , so if you want to emulate my examples download  my source code (it includes a modified country.sql file ) . This code is for demonstration , I would made some re-factoring steps before releasing it into a  production environment . For example this code use the old “Mysql” extension to query the database , there is nothing wrong with this extension but the official php.net web-site recommends to all  developers to “jump” to the new “Mysqli” extension as the old extension will not be supported in future releases . Also , I use a verbose code-signature so that newbies can follow along . They should have at least a basic understanding of PHP – Mysql and JQuery  concepts .

Infinite scrolling is divided in two files : index.php  and jquery.loadMoreComments.php . The first file is the actual file that is accessed by the browser while the second file is queried only by AJAX and will return HTML code . On real world environments , I would use JSON instead of  HTML . But as aforementioned my intention is to be newbie friendly .

Index.php :

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<?php 
mysql_connect("localhost", "root" , "");
mysql_select_db("world");
?>
<div id="postedComments">
<center><h1 style="color:blue;font-size:64px"> Welcome , Scroll to the bottom </h1> </center>
<?php 
$SQLquery = mysql_query("SELECT * FROM World_country ORDER BY id ASC LIMIT 0,30");
$lastId ;
while($data = mysql_fetch_object($SQLquery)){
$id = $data->id;
$name = $data->Name ;
$continent = $data->Continent;
$population = $data->Population ;
echo "
<div class='postedComment' id=\"$data->id \">
<center>
<b>Country : </b>$name <br /> 
<b>Continent : </b>$continent<br/>
<b>Population : </b>$population 
<i style=\"font-size:small;color:blue\">Index : $id</i>
<hr /> 
</center>
</div> 
" ;
}
?>
</div>
<div id="loadMoreComments" style="display:none;" > <center>Dimitrios</center></div>
<script type="text/javascript">
 $(document).ready(function() { 
$(window).scroll(function() {
   	if($(window).scrollTop() == $(document).height() - $(window).height()) {	
	$('div#loadMoreComments').show();
	$.ajax({
	url: "jquery-loadMoreComments.php?lastComment="+ $(".postedComment:last").attr('id') ,
	success: function(html) {
	if(html){		
	$("#postedComments").append(html);
	$('div#loadMoreComments').hide();
	}else{		
	$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>End of countries !!!!!!!</h1></center>");
	}
	}
	});
	}
	});
	});
</script>

jquery.loadMoreComments.php :

<?php 
mysql_connect("localhost", "root" , "");
mysql_select_db("world");
if($_GET['lastComment']){
$sqlQuery = mysql_query('SELECT * FROM World_country WHERE id > "'.mysql_real_escape_string($_GET['lastComment']).'" ORDER BY id ASC LIMIT 0 , 30');
$val = $_GET['lastComment'];
while($data = mysql_fetch_object($sqlQuery)) {
$id = $data->id;
$name = $data->Name ;
$continent = $data->Continent;
$population = $data->Population ;
echo "
<div class='postedComment' id=\"$data->id \">
<center>
<b>Country : </b>"."$name <br /> 
<b>Continent : </b>" ."$continent<br/>
<b>Population  : </b>"." $population<br>
<i style=\"color:blue\">Index nr."."$id</i>
<hr /> 
</center>
</div> 
" ;

}

}

If you need help don’t hesitate to post a comment . Happy coding 🙂

Comments»

1. Michael - January 2, 2012

I’m trying to use this to load user statuses. The javascript seems to work but it doesn’t send the variable “lastComment” to the php script. What could be the reason for this?

tournasdimitrios1 - January 2, 2012

@Michael
You have the option to download the source-code of this article and simulate its functionality . Is your code syntactically correct ? Upload your code to pastebin.com and post the link into this comment section . I’ll try to help you .

2. Michael - January 2, 2012

The page works fine without the ajax. I just wanted to use the infinite scroll instead of using overflow and having a scroll bar. Your way is much more user friendly. By the way, thanks for your help. Out of all the ways i’ve seen it done, I think yours is the best thus far.
pastebin.com/pEWnxf1A

tournasdimitrios1 - January 3, 2012

@Michael
Try to change table’s id .

<table class="postedStatus" id="'.$status_id.', postedStatus" style="font-size:10pt;width:100%;">
//Replace it to 
<table class="postedStatus" id="'.$status_id.'" style="font-size:10pt;width:100%;">

For debugging purposes , bypass AJAX’s query-string , by manually passing “lastStatus” to your Mysql-query :

$sqlQuery = mysql_query('SELECT * FROM status WHERE status_id < 55 ORDER BY status_id DESC LIMIT 0 , 7');

Hope it helps , let me know .

3. Michael - January 3, 2012

When I replace $_GET[‘lastStatus’] with 55 It returns “there are no more statuses” which is the else clause in the javascript function. Should I be passing another variable such as the user_id? When I run the query in mysqlAdmin, it returns a list of statuses. When I use or die(mysql_error()), no errors are returned. and If I cause a error on purpose, I get the syntax error in the LoadMoreStatuses div each time I get near the bottom of the page, where the loading would take place. So I know the javascript is functioning properly. This has really got me at a lose. By the way, sorry for chopping up your code, I just thought I’d be able to incorporate it into my existing script. I don’t believe that it has to do with the javascript/ajax. I think I must be missing something in my php script . Any other debugging I should do?

4. Michael - January 3, 2012

By the way, when I alter my php script to include the user_id as $_GET[‘user_id’] the undefined lastStatus error doesn’t come up, but it still doesn’t return the proper results. Sorry to waste so much of your time.

tournasdimitrios1 - January 3, 2012

@Michael
I have the sense that your table schema (structure) is wrong . Let me explain :
The Mysql query in my index.php is as follows :
$SQLquery = mysql_query(“SELECT * FROM World_country ORDER BY id ASC LIMIT 0,30”);
1) The “id” is pointing to a column witch is :
`id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY
2) This id is assigned to
<div class=’postedComment’ id=\"$data->id \">
3)My first query will display 30 div’s with increment id-number , so my last div is :
<div class='postedComment' id="30"> (starting counting from 1)
4)Javascript identify the id of my last div , ie 30 , and create the query string
$(“.postedComment:last”).attr(‘id’)
url: “jquery-loadMoreComments.php?lastComment=30”

5)The second file ,MoreComments.php, structures an Mysql-query with “lastComment” and returns results
mysql_query(‘SELECT * FROM World_country WHERE id > 30 ORDER BY id ASC LIMIT 0 , 30’);
6)The browser appends now 30 more div’s where the last div is like :

<div class='postedComment' id="60">

Loop goes on until Mysql has no more results , so javascript will display .
End of countries !!!!!!!

Your “$_GET[‘lastStatus’]” has to be an numeric value that points to an auto-increment column of your table . Mysql’s query will use this value as an pointer to return results (if any result is left ) .
Hope it helps , let me know .

5. Michael - January 3, 2012

Some more info, when I user firebug it does show that the lastStatus number in the Params is correct. It just doesn’t seem to be passing it on the the PHP script correctly.

6. Michael - January 3, 2012

And I have also noticed that the java script only runs on the profile page of the user where the user_id = $_SESSION[‘user_id’]. For instance, when I go to someone elses profile, the javascript doesn’t even fire when I get to the bottom of the page.

7. Michael - January 3, 2012

I’ll figure it out. This is the first time I’ve ever asked for help from anyone. I’ve usually been able to figure out what is cause a particular error. It’ll just take some time. Thanks for all your help tournasdimitrios1

8. Michael - January 3, 2012

I’m thinking that maybe I need to somehow put the user_id in the java script parameters and pass that to the php script as well. I’m new to all of this but I’m learning.

9. Michael - January 3, 2012

And also the statuses are auto incremented but they are in a table of their own. So user 1 may have statuses with status_id = 1, 32, 46, 95 and user 56 may have statuses with status_id’s = 2, 50, 99, 150. The only thing that distinquishes user 1’s statuses and user 56’s statuses from each other are their user_id. I thought that with the php query I could just pull the statuses that are associated with each particular user by their user_id’s. Like (“SELECT * FROM status WHERE status_id < '"GET_['lastStatus'] AND user_id = $user_id ORDER BY status_id DESC LIMIT 0, 7") and just return the statuses less than lastStatus and for that particular user.

10. michael - January 4, 2012

Just wanted to let you know that I have working now. The issue was with the PHP query. Thanks for all your help.

11. michael - January 4, 2012

One more thing, it works on safari, IE and chrome but doesn’t on firefox. What would be the cause of that?

tournasdimitrios1 - January 5, 2012

@michael
Sorry for the delay , I had deadline schedules with my freelance job .
Thanks for your feedback .
The solution that I can apply right now is (Just replace the “script” block into the “index.php” file . ):

<script type="text/javascript">
 $(document).ready(function() { 
 $("#postedComments").append( "<p id='last'></p>" );
 // console.log("Document Ready p-tag appended"); // ignore it's just for debugging
$(window).scroll(function() {
 //console.log("Console Window scroll function"); // ignore it's just for debugging
 var distanceTop = $('#last').offset().top - $(window).height();		
	if  ($(window).scrollTop() > distanceTop){
	$('div#loadMoreComments').show();
	$.ajax({
	dataType : "html" ,
	url: "jquery-loadMoreComments.php?lastComment="+ $(".postedComment:last").attr('id') ,
	success: function(html) {
	if(html){
	$("#postedComments").append(html);
	$("#last").remove();
	$("#postedComments").append( "<p id='last'></p>" );
	$('div#loadMoreComments').hide();
	}else{		
	$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>End of countries !!!!!!!</h1></center>");
	}
	}
	});
	}
	});
	});
</script>

Demo of the new version is here <<<<< . This weekend I’ll also update the article . Hope it helps .

12. Katie @ Women's Magazine - January 12, 2012

Unfortunately, your source code is not working for me. I created a new table inserted your .sql file, updated the database connectivity then nothing. It’s not working.

13. tournasdimitrios1 - January 12, 2012

@Katie
The solution is given on my previous (last comment ) . Just follow the instructions and replace the “script” block of index.php with the new code .
I’ll try to update the source-code in a couple hours .
I made the test on all browsers , normally you shouldn’t have any problem anymore , but in case … let met know .
Sorry for the inconvenience .

tournasdimitrios1 - January 12, 2012

Source code uploaded :
The code is tested on Windows-XP/Wamp and Centos5.5/Apache2(Linux) with :
Chrome 16.0.91 — FF7.01 — IE8 — Netscape9.1 — Safari 5.1
Download code from here >>>>
Live Demo >>>>>>
I have to emphasize that this code was the beginning of an idea , not a final production code (no security measures where taken to sanitize query data , the returned data would be in JSON format , Database interactions would be made with PDO or Mysqli ) .

14. JimS - May 12, 2012

Thanks for this example. Shouldn’t the jquery parameter:


$("#postedComments").append(html);

be:


$("#loadMoreComments").append(html);

I realize it works the way you have it, but otherwise what is the purpose of the div #loadMoreComments?

Thanks again ~ Jim

tournasdimitrios1 - May 14, 2012

@Jim$
The concept is as follows :
if (ajax-request returns data) {
append the returned data on the "#postedComments" div
}
else
{
show the "#loadMoreComments" div and append the " End of countries !!!!!!! " message on it .
}

I made a mistake , the naming convention is misleading , #loadMoreComments could be named #noMoreComments .

15. Patrick - August 7, 2012

ufff que Util me resulto este post! aleluyah!!!!!

16. mehran - August 9, 2012

thanks ,for this infinite Scrolling help, i am a littel bit change in your script , mysql_fetch_object change to mysql_fetch_array function .

tournasdimitrios1 - August 9, 2012

@mehran
You are welcome .

17. Wouter - August 26, 2012

It’s awesome to have something like this. I got it working when I edited your script in the ‘testing area’ http://www.basementonline.nl/infinitescroll/ But now that I embedded it in my website it doesn’t load the ‘LoadMore’ http://www.basementonline.nl/index/concerts/ What am I doing wrong?

Wouter - August 26, 2012

Something goes wrong when entering the loadMoreComments file. If I put the filename without the parameters in the javascript it does load, but infinitely loads my whole website repeatedly.

tournasdimitrios1 - August 26, 2012

@Wouters
1)Use only the code that is published on my GitHub repo .
2)I have to know more about your environment (platform , version of PHP).
3)Open the file ” javascript/custom_jquery.js” and un-comment the “console.log” lines (by removing the two backslashes “//” . I will try to debug the code from my location .
ps Don’t forget to store the changes you made on step 3 🙂

Wouter - August 26, 2012

1) I did that
2) PHPversion 5.3.15. What do you want to know?
3) Done.

tournasdimitrios1 - August 26, 2012

@Wouters
My code was designed to call “jquery-loadMoreComments.php” with integer arguments (?lastComment=23 or ?lastComment=44 or ?lastComment=77 ….) . You made some changes on the code and the code requests the file with arguments in the format of “http://www.basementonline.nl/jquery-loadMoreComments.php?lastComment=2012-01-07” .
For security reasons , I pass all code via PHP’s filter function , which rejects your request (as it’s probably not valid) . For some reason the URL request is rejected ,try to refactor your code .
Or paste the code on “pastebin.com” , so that I can test the code .
Thanks for your feedback , and please keep me in touch with your modifications …..

Wouter - August 26, 2012

As you might have figured out it is a date. I need that parameter to properly feed the sql-query. If I used the original code I have to ORDER BY id. But my query needs to be ORDER BY date. Therefore I need that parameter. I hope you understand what I mean. Thank you so much for your time and help! If necessary I will find out how pastebin works and pass you the code.

18. Wouter - August 26, 2012

I could format the date to a Unix timestamp and reformat it before I execute the query? But would that work? Is there maybe a better solution?

tournasdimitrios1 - August 26, 2012

@Wouter
That sounds a great idea .
Each record in the database should be identified by an unique number . Native Date isn’t a option because you might have two records with the same date . PHP’s microtime is probably a better choice .
ps Keep in mind that Unix – Mysql time-stamps are totally different
A last note : When finishing with your code-refactoring process , don’t forget to comment all “conslole.log” lines .I have noticed that some IE browsers freeze when these lines are enabled .

Wouter - August 27, 2012

I don’t need mysql timestamp. I only needed a way to pass the date in INT through your script, but I converted it back with date(“Y-m-d”,$var). I realize that I might miss some records if they are on the same date (namely if some 30th record has the same date as the next record). I will consider adjusting my database to prevent this. Thank you so much for your help. Next thing will be adjusting your script such that it loads loadMoreContent only when bottom is reached, not at every scroll as it seems to work right now. But that’ll come some other day. This is just a hobby project of mine. It’s really great that there are people like you around on the net!

tournasdimitrios1 - August 27, 2012

@Wouters
1)The “time()” function should be adequate to distinguish each record in the database as it expresses Unix epoch in seconds . Probably you have to re-factor the schema of your Db-table .
2) Actually the Ajax-request should be enabled when the end of the page is reached . At least it works corectly on my development and production server (tests where made on Linux , Mac and Windows XP/7 — and with many browsers) . Many reasons could force the script to malfunction , for example , a Js-library conflict . At some time , when you are ready , un-comment again the “console.log” lines .

Wouter - August 28, 2012

And the query for loadMoreComments:

SELECT *
FROM
(SELECT @rownum := @rownum +1 AS rank, table1.*, table2.*
FROM (SELECT @rownum :=0) AS r, table1
JOIN table2 ON table1.table2id = table2.id
WHERE online =1
ORDER BY table1.date DESC) AS a
WHERE rank > ‘”.$filtered.”‘
LIMIT 0 , 30″;

Wouter - August 27, 2012

I found a different solution by adjusting the SQL-query:

SELECT @rownum := @rownum +1 AS rank, table1.*, table2.* FROM (SELECT @rownum :=0) AS rowno, table1
JOIN table2 ON table1.table2id = table2.id
WHERE online =1
ORDER BY table1.date DESC
LIMIT 0 , 30

I think other people might run into this if they don’t want to ORDER BY id. I know my query is more complicated than a simple explanation would need, but I had a hard time figuring out where to exactly place which command. Again thanks for your script!

19. Kevin - August 29, 2012

I’m experienced with PHP but not much a javascript coder. I have the script working (thanks) in a dev environment but when there is no more data I don’t get the “End of countries !!!!!!!”.

I am not using this in a blog so I still have some work to do understanding all of the jQuery and divs. Can you explain what my php code for the loadMore…php needs to send back in order for the if(html) …. else custom jquery.js code to present the else section?

Thanks for the script and explanations.

tournasdimitrios1 - August 29, 2012

@Kevin
A database query is “triggered” from JQuery’s ajax call . If the database returns results , a “while” loop constructs a HTML-response which is then “echo-ed” back to the ajax-call , else nothing is returned . JQuery parses the result and if it’s empty (no HTML-code) the proper message is appended into the DOM-model .
The best way to understand the script is to open your browser’s developer tool .

  • Chrome : CTL+shift+i -> network-tab -> Headers and Response tabs .
  • Firefox : First install the firebug plugin . F12 -> Net tab -> Headers and Response tabs .
  • IE >= 9 : F12 -> Network tab -> Start capturing -> Go to detailed view -> Headers and Response tabs . (Older versions of IE9 have no network tab ,only external tools can be used ==Fidler2==)

From the browsers developer-console tool we can clearly explore the “Header” and “Response” messages . It’s clearly seen that even when “end-of-page” is reached , ajax keeps querying the database (which responses with an empty message ) . Certainly this infinite database query isn’t acceptable on production environments . The next version of this script will take care of this .
The developer-console can also be used for debugging JavaScript code . The “console” tab displays JS-errors and also custom messages . Paste the following code elsewhere into the JQuery-script blog and open the console tab .
console.log("This is my custom message!!!!!! ");
ps This link is a good introduction to jQuery’s selectors and traversal model (DOM) .

20. Wouter - August 29, 2012

@tournasdimitrios1: The script still fires at each scrollaction, but beyond that the script is working great! I uncommented the console.log’s. Hopefully you can see what’s going wrong

tournasdimitrios1 - August 29, 2012

@Wouters
Observe the following code-snippets .

 
##################
###  Your code ##
##################
<div class='postedComment' id="1">
<div id="con_concert">
<div id="con_"><a href="http://www.basementonline.nl/index/concert/401/">20 August 2012</a><br />18 Photo's</div>
<div id="con_"><a href="http://www.basementonline.nl/index/concert/401/924/">Malgosia Fiebig</a> (18)<br /></div>
<div id="con_">Domtoren<br />Utrecht</div>
<div id="con_"><img src="http://www.basementonline.nl/concert2/401/924/thumbs/tn_IMG_0641.jpg" /><br />Malgosia Fiebig</div>
</div></div>

#####################
####### My code #####
##################### 
<div class='postedComment' id="1 ">
<center>
<b>Country : </b>Germany <br /> 
<b>Continent : </b>Europe<br/>
<b>Population : </b>82164700 
<i style="font-size:small;color:blue">Index : 1</i>
<hr /> 
</center>
</div> 

NOTICE : In HTML , each div must have a unique name , you have circumvented this basic rule . As JQuery works heavily with the DOM-model this causes probably the malfunctioning . Change the div’s to Class tags (of course your CSS should be adapted accordingly) . This might solve the problem .

Wouter - September 1, 2012

I never really realised that it was an actual error, but now that I come to think of it… Anyways, I corrected it, but it didnt help fixing the error. Again thanks for your time and effort

tournasdimitrios1 - September 2, 2012

@Wouter
For some reason , the Jquery custom code can’t identify some parts of the DOM .
Replace the code of javascript/custom_jquery.js with this code .
Or rename the old file (just for back-up) and create a new file where you paste the new code . To be sure , use Ctrl+a , Ctrl+c and Ctrl+v when copy pasting the code .
The new code has some extra lines of code that will assist during debugging .
Update : A new version is released on GitHub (V0.4) . The file custom_jquery-debug.js is available for download . If there is need for client-side debugging , import this file into index.php instead of the defauld file (custom_jquery.js) .

Wouter - October 3, 2012

@tournasdimitrios1: the page you link to that should contain the code says: You are seeing this page because website has reached CPU usage limit of the server, and it was temporarily disabled.

tournasdimitrios1 - October 3, 2012

@Wouter
From the beginning of this Blog ,2.5 years ago , my plans were to create a non-profit “interactive corner” . My only option was to choose free hosting providers . This option worked fine as my monthly visitors are in the range of 20000 . The second web-host (tournasdimitrios.host56.com) is just used to demonstrate functionality of some of my published articles . No more than 30 visits/per day are redirected into this second web-host . Suddenly , they told me that my monthly free trafic is exceeded and that I have to upgrade with 5$ / month . I have no complains , as it’s a free service and I must comply to their rules .

If you plan to continue the debugging process (from the point that was left on our previous comment) , enable the new “jquery-loadMorecomments–debug.php” script .

Wouter - October 3, 2012

@tournasdimitrios1: Yes I would like to. I loaded the new debugscript

tournasdimitrios1 - October 4, 2012

@Wouter
Try to solve the following , before we can start debugging .

The requested URL /index/concerts/jquery-loadMoreComments.php?lastComment=30 was not found on this server.

Wouter - October 4, 2012

Done

tournasdimitrios1 - October 5, 2012

@Wouters
First try to solve the following error message :

XMLHttpRequest cannot load http://www.basementonline.nl/jquery-loadMoreComments.php?lastComment=30. Origin http://basementonline.nl is not allowed by Access-Control-Allow-Origin.

Then open custom_jquery.js file and change the following line :

if ($(window).scrollTop() > distanceTop){

to :

if($(window).scrollTop()+$(window).height() == $(document).height()){

Wouter - October 6, 2012

@tournasdimitrios1: Where do you encounter that error message? I am not able to reproduce it. I looked into the meaning of the error and it has to do with CORS. Something with crosssite scripting. I came across all kinds of Apache settings of which I don’t know much. Is your script depending on Apache settings or is it something else that triggers the error?

The good news is: with suggested change of code the script DOES work. I have got only one question left: Is it possible to let it fire a bit earlier, such that it is already appending lines before a visitor gets to the bottom of the page. I tried adding and subtracting some number to “$(document).height())”, but the script didn’t like that.

Once again: thank you so much for your help. I just can’t put to words how happy I am with all your effort.

tournasdimitrios1 - October 7, 2012

@Wouter
Are we talking about the same link ?
When I try to debug , only the first 30 posts are working normal . When the AJAX-request try’s to load the next 30-posts then the aforementioned error message is displayed on my browser’s console window (without response to the AJAX’s request) . This is my explanation :
The “Same Origin Policy” , enforced by browsers is an important security concept for a number of browser-side programming languages (JavaScript ,Flash-Actionscript , Java-applets and Silverlight) . In simple words , you cannot fetch data/content from other domains/sub-domains than your’s (the requesting domain) with straight AJAX calls . There are different ways to bypass these restrictions , for example , Flash uses a cross-domain policy file on the server . JavaScript can use

  • JSONP to request content from other domains (this options is not without criticism –related to security) .
  • Apache’s http.conf file can be configured to allow cross-domain AJAX-requests (that’s probably not an option on shared-hosting , though , .htaccess directives could be an alternative solution )

.
My script wasn’t meant to work cross-domain and I’ll not support such functionality .



We could use different solutions to let the script fire a bit earlier , just by referencing the DOM a bit differently . A quick solution that came into my mind right now is :
if( $(window).scrollTop() + $(window).height()+400 >= distanceTop){
or
if( $(window).scrollTop() + $(window).height() + 600 >= $(document).height()){
These solutions where tested on my localhost box .

Wouter - October 7, 2012

Yes we are talking about the same link. Which browser are you using? I think I found it though. I always use FF to develop, but as I tested other browsers I found out that IE was the only one that your script didn’t work. Even worse: when I started the console and loaded my page the whole browser crashed while loading some other apparently buggy javascript that I don’t care much for (anymore). So I removed that bit and now it works. Thanks for all the explanations and information. I will check those out some time this week. It might be usefull some day. I hope that my buggy script was triggering your error as well and that as from today on it works with everyone. If not, I’d be glad to try and figure out what causes the error, but as I can not reproduce the error, this could become quite difficult. The solution that you offered for letting the script fire earlier seems to be working perfectly. Thanks!

Wouter - October 7, 2012

And I forgot to add that nothing’s loaded from other domains whatsoever. So I don’t understand why that errormessage is triggered

tournasdimitrios1 - October 7, 2012

@Wouters
Tests were made on WindowsXP/7 and MacBook-Pro (with all major browsers) , and still I get the error message on all browsers .
The following screenshots are taken on my MacBook :
Image Hosting by PictureTrail.com
and this screenshot
Image Hosting by PictureTrail.com
Browser’s restriction does also apply to sub-domains (that’s for sure) , not for directories (not sure about that) .
That’s weird , how does the script work only on your location ?
I have even tried to use a proxy-server located in the Netherlands (to masquerade my location) , but unfortunately proxy’s do not bypass all scripts (js) , so test could not be achieved .
I’m scratching my head and really want to find out what is going on .

Wouter - October 10, 2012

This is getting weird and interesting at the same time. I tested this on my phone, at work, I had one of my friends test it at home. This is on android, W7, W8 with different browsers. After being crazed and staring at my screen for a way too long while I realize that I do have some external scripts. The social buttons at the botttom. I have turned this script off now. Does this circumvent the problem?

tournasdimitrios1 - October 10, 2012

@Wouters
No , the error still exists . The Ajax-request is isolated from the test-page as it communicates with “jquery-loadMoreComments.php” , so there is no intervention with the test-page . A possible cause could be : an image located into another domain (ImageShack , Flickr — Photo Sharing services) or even on a sub-domain of your server .

Wouter - October 10, 2012

They are all taken from the same subdir in the same domain. I know this for sure since I wrote all the code myself. It is impossible to load form a different location since the directory from which the pics are taken is hardcoded in my scripts. I will try to reproduce the error in the coming weeks and try to think of a cause. It’s weird.

21. Jim Starkweather - October 10, 2012

Did your update on Aug 11, 2012 fix any issues with JQuery 1.8.2 compatibility? I just noted that when I updated by core JQuery from 1.7.2 to 1.8.2 the auto scroll started to fail (in Chrome at least).

Thx… great script btw!

tournasdimitrios1 - October 10, 2012

@Jim Starkweather
Jquery is imported from Google’s CDN network , a trick is not to specify the version , so Google will deliver the latest stable version (as of this writing v.1.8.2)
src=”http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js”

22. Wouter - October 12, 2012

@tournasdimitrios1: I am almost sure I found out what the problem is. Can you confirm that the error is gone when you test the script with ‘www.’ in front of the domainname in the addressbar and that if you test without ‘www.’ it fails?

tournasdimitrios1 - October 12, 2012

@Wouters
Bingo !!!! , it works 🙂
Important last step : update your code . This will disable Ajax-calls at end of DB-results (save your server from unnecessary work-cycles) .
Just a question , can I place a link on my article to your page ? . As of this writing ca 50 visits/day are reading my article and 10/day are using my demo-page .
Update :
http://www.example.com and example.com are two different domains as far as the browser is concerned, apparently, even though they both direct to the same site. Read more on SO .

Wouter - October 12, 2012

I am so happy that we finally beat the error! I updated my code. Of course you can link to my page. If you want to use our case for extra explanation or just want to delete or organize the comments, feel free!

23. ohhey - October 19, 2012

I’m trying to create a twitter feed style application, and have it working beautifully, thanks to this piece of code. What I’m having trouble with is calling the unique id’s for each of my divs produced in the infinite scroll to be used in another piece of js on my page that would create a unique popup box for each when a link was clicked.

Any suggestions?

I should note, I got it to work when I create both the main div and hidden div in the masterLoader.php file, but the popups won’t work after more are loaded onto the page.

Thanks

tournasdimitrios1 - October 19, 2012

@ohrey
Referencing a div into the DOM model with JQuery can be done with different ways . An example that came right now into my head is >>>>> .

24. yakub - March 21, 2013

Hello, thank you for this post. But its not working in ie (version ” 7.0.5730.13). Can you please help me to solve this.

tournasdimitrios1 - March 21, 2013

@yakub
IE-7 is an extremely old browser , and I won’t spend time to tweak/test my code on this version . According to “Browser Trends February 2013” , IE7 has only 0.7% share .
Thanks for commenting on this blog .

yakub - March 21, 2013

Thank You for the reply, I am facing some error while changing the code as per my requirement. Can you please help me out.

Below is the code in index page :


Welcome , Scroll to the bottom
company_id;
$name = $data->companyname ;
$continent = $data->company_profile_id;
$population = $data->addedby ;
echo ”
company_id \”>

Country : $name
Continent : $continent
Population : $population
Index : $id

” ;
}
?>

Dimitrios

$(document).ready(function() {
$(“#postedComments”).append( “” );
// console.log(“Document Ready p-tag appended”); // ignore it’s just for debugging
$(window).scroll(function() {
//console.log(“Console Window scroll function”); // ignore it’s just for debugging
var distanceTop = $(‘#last’).offset().top – $(window).height();
if ($(window).scrollTop() > distanceTop){
$(‘div#loadMoreComments’).show();
$.ajax({
dataType : “html” ,
url: “jquery-loadMoreComments.php?lastComment=”+ $(“.postedComment:last”).attr(‘id’) ,
success: function(html) {
if(html){
$(“#postedComments”).append(html);
$(“#last”).remove();
$(“#postedComments”).append( “” );
$(‘div#loadMoreComments’).hide();
}else{
$(‘div#loadMoreComments’).replaceWith(“End of countries !!!!!!!”);
}
}
});
}
});
});

and this is code what it is in jquery-loadMoreComments.php page

“if($_GET[‘lastComment’]){

$sqlQuery = mysql_query(‘SELECT * FROM company_details ORDER BY company_id > “‘.mysql_real_escape_string($_GET[‘lastComment’]).'” ORDER BY company_id ASC LIMIT 0 , 30′) ;
$val = $_GET[‘lastComment’];
echo $val;
while($data = mysql_fetch_object($sqlQuery)) {
$id = $data->company_id;
$name = $data->companyname ;
$continent = $data->company_profile_id;
$population = $data->addedby ;
echo ”
id \”>

Country : “.”$name
Continent : ” .”$continent
Population : “.” $population
Index nr.”.”$id

” ;

i am getting the error as “Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\Scrolling\jquery-loadMoreComments.php on line 9”

Thank You

yakub - March 21, 2013

Sorry for troubling you. Got it solved. i was having problem with writing the code.

Thank You very much

yakub - March 22, 2013

how can i add more variable to pass to the php page.

I have to pass 3 more values to the “jquery-loadMoreComments.php”. ie. i have to pass “category”,”state”,”area”.

I don’t have much knowledge in jquery and ajax, so please help me out on this.

Thank You

25. yakub - March 22, 2013

how can i add more variable to pass to the php page.

I have to pass 3 more values to the “jquery-loadMoreComments.php”. ie. i have to pass “category”,”state”,”area”.

I don’t have much knowledge in jquery and ajax, so please help me out on this.

Thank You

26. zerounonews.com (@zerounonews) - July 30, 2013

Hello,
can i use this with my gallery php from folder image without database?

Thanks.

tournasdimitrios1 - July 31, 2013

@zerounonews
Of course , the code must be changed accordingly though .

27. zerounonews.com (@zerounonews) - July 31, 2013

What code i modify? I’m newbie
i use this script for load image from folder

<?php
$directory = "imgfold/animals/*.jpg";
$files=glob($directory);
$files=array_map("basename", $files);
foreach($files as $ch => $file){
    echo "<li><a href=\"imgfold/$file\"><img src=\"imgfold/thumb/$file\" alt=\"- $ch\" /></a></li>"; 
}
?>
tournasdimitrios1 - August 1, 2013

Just because I’m a fan of SPL’s functionality (which is more efficient than Glob) .

$directory = './pictures';
$pictures = array() ;
$iterator = new DirectoryIterator($directory );
foreach ($iterator as $fileinfo) {
    if (!$fileinfo->isDot()) {
		array_push($pictures , $fileinfo->getFilename() ) ; 
    }
	}
echo '<pre>' ; 
print_r($pictures) ; 

// Implement a pagination functionality
$from = 5 ; 
$to = 10 ; 
for ($i = $from ; $i <= $to ; $i++) {
    echo $pictures[$i] . '<br>'  ;
}  

For hierarchical data (nested directories) , use “RecursiveDirectoryIterator” though .
Hope , this is an starting point for you .

28. Altaf Hussain - October 26, 2013

Well written article. Helped me to implement the infinite scroll feature.

29. Julio Yuls Guzmán - January 12, 2016

Hi, can you help me? I got an error.
When loading the new query, throws me an error on the console:
[HTTP / 1.1 403 Forbidden 17ms]
Thanks in advance

Tournas Dimitrios - January 12, 2016

Hi Julio,
403 errors are almost always caused by issues where you’re trying to access something that you don’t have access to.The 403 error is essentially saying “Go away and don’t come back here.”.
Sorry for my general answer, I have no information about your “server sett-up” .

Julio Yuls Guzmán - January 12, 2016

Thank you. Sorry, it has something to do with shipping by GET? The tendo hosted server where the project does not allow me to make changes for this error.

Sorry, I’m starting with this

Tournas Dimitrios - January 12, 2016

Sorry , my definition “server sett-up” has been misunderstood (100% my fault) , I didn’t mean a server configuration per se , but a general authentication issue. Usually, a server returns a “403” HTTP status code , when access to a page or resource is absolutely forbidden for some reason . For instance, the user has to log-in with username/password credentials , before accessing specific pages/resources.

Julio Yuls Guzmán - January 13, 2016

Yes, I saw my problem lol. Now it does not allow me to view the new records to the second query. Throws Exception


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s