I can't figure this problem out.
I use this JS call to load ajax content when I arrive at the bottom of the page:
$(window).scroll(function() {
if($(window).scrollTop() + window.innerHeight == $(document).height() ) {
and it works well, but now I want to change for loading the content when I reach the bottom of my container... I am trying this:
$(window).bind('scroll', function() {
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight) {
It loads the content when I reach the bottom of the container, but it loads it like 5 times... It's like as if it does a loop 5 times each time.
I want it to load ONCE, then when I go back DOWN the page and I reach the "NEW BOTTOM" of the container, load data 1 more time...etc
I tried many variables, but I can't figure it out. Any suggestions?
FULL AJAX CODE
$(window).bind('scroll', function() {
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight) {
$('div#loadmoreajaxloader').show();
$.ajax
({
url: "loadmore.php",
method: "get",
data: { page: pageNumber, perpage: perPage, search: "<?=$search?>", blogtag: "<?=$blogtag?>"},
success: function(html)
{
if(html)
{
$("#postswrapper").append(html);
$('div#loadmoreajaxloader').hide();
pageNumber++;
}
else
{
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
}); // close AJAX
} // close if()
}); // close $(window)
Scroll top is executed few times after you have the set true for the condition:
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight)
Here is a test fiddle for the window scroll, it always fires when you move the scroll and your condition does not limit the inner scope to execute only once.
test scrool event
Edit: simplest way is to use a lock while the ajax request is executing and while you are updating the UI with new content.
Why build something like this yourself when there are plenty of libraries out there? Just use an infinite scroll library that meets your needs. As you already use jQuery:
http://www.sitepoint.com/jquery-infinite-scrolling-demos/
But that's not the answer to your question. You should add a boolean to check if you're already loading new content. Let's say: loading. Initially set this boolean to false. If you request new data, set the boolean to true and in the check scroll statement add a check for this boolean. After adding the newly loaded content set the boolean to false again.
Fully working code:
var loading = false;
$(window).bind('scroll', function() {
if(!loading && $(window).scrollTop() >= ($('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight)) {
loading = true;
$('div#loadmoreajaxloader').show();
$.ajax({
url: "loadmore.php",
method: "get",
data: {
page: pageNumber,
perpage: perPage,
search: "<?=$search?>",
blogtag: "<?=$blogtag?>"
},
success: function(html) {
if(html) {
$("#postswrapper").append(html);
$('div#loadmoreajaxloader').hide();
pageNumber++;
loading = false;
} else {
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
}); // close AJAX
} // close if()
}); // close $(window)
Related
My scrolled navbar return to default when i reload my page in the middle of the page
Here is my website photos look here
My javascript codes :
$(document).ready(function($){
$(window).scroll(function(){
$scrol = $(document).scrollTop();
if ($scrol > 50 ) {
$('.header').addClass('header6');
$('.logo').addClass('logo5');
$('.about').addClass('about5');
$('.about:hover').addClass('about5:hover');
$('.navbar').addClass('navbar5');
$('.nav').addClass('nav5');
}
else{
$('.header').removeClass('header6');
$('.logo').removeClass('logo5');
$('.about').removeClass('about5');
$('.about:hover').removeClass('about5:hover');
$('.navbar').removeClass('navbar5');
$('.nav').removeClass('nav5');
}
});
});
i wait answers
THANK YOU
Just run your function when the page loads to update your header :
I also added some modifications to optimize your code, as stated by #jeremy-thille
function updateScroll(obj){
if ($(document).scrollTop() > 50 ) {
obj.header.addClass('header6'); //Use the previously stored JQuery requests
obj.logo.addClass('logo5');
obj.about.addClass('about5');
obj.navbar.addClass('navbar5');
obj.nav.addClass('nav5');
}
else{
obj.header.removeClass('header6');
obj.logo.removeClass('logo5');
obj.about.removeClass('about5');
obj.navbar.removeClass('navbar5');
obj.nav.removeClass('nav5');
}
}
$(function(){ //New way to wait for the document to be loaded
//Store JQuery calls to reduce processing time
var storedObjects = {
header: $('.header'),
logo: $('.logo'),
about: $('.about'),
navbar: $('.navbar'),
nav: $('.nav')
};
updateScroll(storedObjects); // Will update your header
$(window).scroll(updateScroll(storedObjects));
});
I have checked all the possible questions that could be related to this but I cant seem to find anything that suits my case, either the answers were not good or incomplete.
In my case I have a html page with some php, displaying competition results. As the competition is live the page with results should scroll to the bottom of the page and then the page should refresh (so the possible new scores come in) and then repeat again and again. What would be the best solution for my problem?
The page size/length would increase as more data will come in the tables which are on results page.
Image:
EDIT:
This code now scrolls to the bottom of the page and then jump back to top and repeat and its exactly what I want, but I would like a page to refresh every time I hit the bottom and after this go to the top.
$(function() {
var pageScan = {
speed : 10000,
loop : true,
delayRestart : 1000,
start : function(){
pageHeight = $('body').height() - window.innerHeight;
pageScan.proc(pageHeight);
},
proc : function(to){
$("body").animate(
{scrollTop: to},
pageScan.speed,
"linear",
function(){
if (pageScan.loop) {
setTimeout(function() {
window.scrollTo(0, 0);
pageScan.start();
}, pageScan.delayRestart);
}
});
}
};
pageScan.start();
});
You can add some JavaScript to your page:
<script>
window.scrollTo(0,document.body.scrollHeight);
setTimeout(function (){location.reload()},5000);
</script>
This might be what you are looking for:
// Test data, ignore
for(i = 1; i < 21; i++) {
$('#results').append('<p>Test Result No.' + i + '</p>');
}
// Check every second (for example) if there is new data
// In this example there is always data
window.setInterval(function(){
update_results();
}, 1000);
// Check for new results
function update_results() {
$.ajax({
type: 'POST',
// Test data, ignore
data: {
html: 'new result'
},
// your ajax.php file
url: '/echo/html/',
success: function(data) {
// Append new results to $('#results');
// You might want to give back an array and loop through it with $.each(data, function() {});
// you might also want to check for "false" if there are no new results
$('#results').append('<p>' + data + '</p>');
// Scroll to bottom smoothly
$('html, body').animate({ scrollTop: $(document).height() }, 'slow');
}
});
}
jsfiddle
In your ajax.php-File you can echo the new scores:
echo json_encode($scores);
Given that $scores is an array of your scores which you probably have from your database.
I have a scroll function
$('#lisr').scroll( function() {
if($(this).scrollTop() + $(this).innerHeight()>= $(this)[0].scrollHeight)
{
//DO some code
}
}
The problem is when I scroll down and it hits the bottom it executes the code twice instead of once, so If I make any ajax call in it, it is made twice, what I am missing in it?
The scroll() function binds to the scroll event - which is fired many times when the user scrolls the page.
Write your code with the assumption that it can be called more than once:
var completed = false;
function doSomeCode() {}
function isAtBottomOfPage() {}
$('#lisr').scroll(function () {
if (!completed && isAtBottomOfPage()) {
doSomeCode();
completed = true;
}
});
jsfiddle: http://jsfiddle.net/kZJ9k/1/
As a more advanced note, you probably shouldn't bind your logic directly to the scroll event; you run the risk of causing lag for your users when scrolling. Read more about this from John Resig:
http://ejohn.org/blog/learning-from-twitter/
Here are my codes for endless scrolling. What I do is unbinding the scroll event until the ajax request finishes. You can also use a variable as a flag and check/change its value before calling ajax request. Hope it helps:
$(document).ready(function(){
$(window).bind('scroll', loadPage);
});
var loadPage = function(){
if($(window).scrollTop() + $(window).height() == $(document).height()) {
$(window).unbind('scroll');
$.ajax({
//Your things here
success: function(result){
// Do success here
$(window).bind('scroll', loadPage);
},
error : function(xhr){ //Do error here }
});
}
}
$('#lisr').scroll( function() {
if($(this).scrollTop() + $(this).innerHeight() > $(this)[0].scrollHeight)
{
//DO some code
}
}
I'm making a simple responsive Wordpress Theme and I want only one page there, and the content loaded via AJAX, so I have an AJAX function:
jQuery(document).ready(function(){
jQuery.ajaxSetup({cache:false});
jQuery("#mainnav a").click(function(){
var post_link = jQuery(this).attr("href");
jQuery("body").load(post_link);
return false;
});
});
It's meant to load entire pages content (entire body) on clicking menu links. And it works well.
But the problem is I have a jQuery script responsible for centering content div:
(function (jQuery) {
jQuery.fn.centerAlign = function() {
return this.each(function(i){
var w = jQuery(this).width();
var ow = jQuery(this).outerWidth();
var ml = (w + (ow - w)) / 2;
var h = jQuery(this).height();
var oh = jQuery(this).outerHeight();
var mt = (h + (oh - h)) / 2;
jQuery(this).css("margin-top", "-" + mt + "px");
jQuery(this).css("top", "50%");
jQuery(this).css("margin-left", "-" + ml + "px");
jQuery(this).css("left", "50%");
jQuery(this).css("position", "absolute");
});
};
})(jQuery);
jQuery(document).ready(function() {
jQuery("#content").centerAlign();
});
That script centers the #content div at reload instatly, so I mean there is no delay. The div is centered from the start.
Problem is when I combine that scripts, because after AJAX loads the entire body, #content div is not positioned for ~1 second (in top-left corner of the page) and then it comes back to its place. So jQuery script works with a delay.
I coulnd't find a solution for that problem, .on and .live don't work for me. I think I could just load each page content into a #content div, not entire "body", but I don't know how to make it.
I'd appreciate if you can help me with that, so it will just resize the #content div with animation, not position it from start.
EDIT:
Ok, I ended up with such code:
jQuery(function(){
jQuery("#mainnav a").click(function(e){
var content=jQuery("#content");
jQuery.ajax({
url: jQuery(this).attr('href'),
dataType: "HTML",
beforeSend: function(){
content.empty();
},
success: function(){
content.load();
},
error : function(){
content.html("<p>Przepraszamy, ale strona jest chwilowo niedostępna</p>");
},
});
e.preventDefault();
})
})
It should work, but the problem is that I can't figure out what should I put in that lines:
success: function(){
content.load();
It workd up to that point. I clears the #content div but when I put content.load("#content"); it loads entire page, with menu and footer. And I want to load just #content content.
EDIT:
Ok. Firebug shows that this code is working, but there is nothing shown within the #content div in broswer window.
jQuery(function(){
jQuery("#mainnav a").click(function(e){
var content=jQuery("#content");
var href=jQuery(this).attr('href');
var text = jQuery(this).find('#content').html();
jQuery.ajax({
url: jQuery(this).attr('href'),
dataType: "HTML",
beforeSend: function(){
content.empty();
},
success: function(){
content
.html(text)
.centerAlign();
},
error : function(){
content.html("<p>Content Unavailable</p>");
},
});
e.preventDefault();
})
})
I think you're on the right track with your new code, you just need to fill out your success function:
success: function( html ){
html = jQuery(html).find('#content').html();
content.html(html).centerAlign();
},
or perhaps (using th1rdey3's idea):
success: function( html ){
html = jQuery(html).find('#content').centerAlign().html();
content.html( html );
},
You could centerAlign #content before placing it inside body. Something like this
var $div = jQuery('<div/>').load(post_link);
$div.find('#content').first().centerAlign();
jQuery('body').html($div.html());
or only loading the content part
var $div = jQuery('<div/>').load(post_link);
jQuery('#content').first().html($div.find('#content').first().html());
I'm having a bizarre issue that I don't know how to solve and was wondering if you guys could help.
A bit of background: I have been asked to create a system where subpages of a page in wordpress are loaded on the end of that page in an infinite scroll. This is working correctly.
They also want the top nav links to load all content upto and including the page they clicked and then scroll to it.
If I scroll down (loading the pages) and then click a top nav link the scroll works correctly. However if I load NO further pages before clicking one of the links, the pages will load, and the scroll will start, but will only get some of the way before stopping. This is due to an incorrect value being given by offset().top. My question is why ?
function ajaxloadnscroll(index) {
//If the page has already been loaded then just scroll to it
if (pages[index].loaded) {
$('html, body').animate({
scrollTop: $("#" + pages[index].name).offset().top
}, 2000);
return;
}
//Loop through pages up to one clicked.
for (i = 0; i <= index; i++) {
current = i;
if (!pages[current].loaded) {
$.ajax({
url: pages[i].url,
async: false,
context: document.body,
success: function(data) {
if (data) {
$("#tempload").before(data);
pages[current].loaded = true;
if (current == index) {
$('html, body').animate({
scrollTop: $("#" + pages[current].name).offset().top
}, 2000);
}
}
}
});
}
}
//Increment current in order to load next page object on scroll.
current++;
return false;
}
Any help you could give me on this issue would be really appreciated!