I have a load more button that appears once the user hits the bottom of the screen / fades out when scrolling up. Like so:
$(window).bind("scroll", function() {
if ($(document).height() <= ($(window).height() + $(window).scrollTop())) {
$("#loadmorebuilds-div").fadeIn();
} else {
$("#loadmorebuilds-div").fadeOut();
}
});
Here is what I use for loading the new content:
$(document).ready(function(){
var pageIndex = 1;
$('#loadmorebuilds-div').click(function() {
$('#buildcontainer').imagesLoaded( function(){
$.ajax({
url: 'includes/loadmorebuilds.php?type=follow&pageIndex=' + pageIndex,
success: function(html) {
var el = jQuery(html);
jQuery("#buildcontainer").append(el).masonry( 'reload' );
$("#loadmorebuilds-div").stop().fadeOut();
pageIndex++;
$("#buildcontainer").masonry()
rowCount = $('#countvar').length;
if (rowCount < 8) {
window.location.replace("http://localhost/buildsanctuary/index.php");
}
}
});
});
});
});
And this part here, checks the amount of returned data and if its less than requested, it means that there is no more data to show.
rowCount = $('#countvar').length;
if (rowCount < 8) {
window.location.replace("http://localhost/buildsanctuary/index.php");
}
The page re-direct is just to test that it was working, what I want is to instead not allow the page to show the load more button again.
How can I go about this?
I tried changing the class e.g.
$("#loadmorebuilds-div").attr("class", "loadmorebuild-divhidden");
But that doesn't work, the hidden class is just display:none.
Thanks.
Sorted this by removing it from the dom with
.remove()
Not sure why i didn't think of this!
Related
Here the button loads data from database. Works fine.
<li class="getmore" id="'.$post_id.'"><a>Load More Posts</a></li>
How can I make this button to get clicked automatically on scroll down to the bottom of the page . simply the infinite scroll.
should i use window scroll function .If yes then how can do it in this code.
I have tried by pasting the ajax code inside this function but not working.
Edit :
1. when I put the Ajax inside scroll function,It shows mysql error in getmore.php.
2. if I put the button class with click function inside scrolling function then it fires too fast that loads the same posts multiple times.
$(document).scroll(function(){
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
}
});
$('body').on('click','.getmore',function(){
var lastelement = $(this ).attr('id');
$.ajax({
type : 'GET',
url : 'getmore.php',
data : 'lastelement='+lastelement,
beforesend : function(){
$('.getmore').html('loading....');
},
success: function(data){
$('.getmore').remove();
$('#recs') .append(data) ;
}
});
});
<?php
$lastelement = $_REQUEST['lastelement' ];
include("connect2.php");
if ($lastelement!=''){
$query = "SELECT * FROM `posts` "
. "WHERE (id < " . $lastelement . " AND "
. "post_keywords like '%home%') "
. "ORDER BY `posts`.`id` DESC "
. "LIMIT 10";
$records = mysql_query($query);
if (mysql_num_rows($records)) {
while($record = mysql_fetch_array($records)){
$cookie_name = 'tcVotingSystem'.$record['id'];
$post_title = $record['post_title'];
$post_id = $record['id'];
$post_date = $record['post_date'];
$post_author = $record['post_author'];
$post_image = $record['post_image'];
$post_image2 = $record['post_image2'];
$post_keywords = $record['post_keywords'];
$post_content = substr($record['post_content'],0,100);
?>
<div>
//posts goes here
</div>
What you want to do is fire off the same Ajax request your button down once the scroll reaches a certain point. So instead of inserting the click event function on scroll, rather fire off your Ajax event
Example:
$(document).scroll(function(){
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
$.ajax({
type: 'GET',
url: 'getmore.php',
data:'lastelement='+lastelement,
beforesend: function(){
$('.getmore').html('loading....');
},
success: function(data){
$('.getmore').remove();
$('#recs') .append(data) ;
}
});
}
});
The above is just an example. As an aside, I would recommend that you create a function for your lazy loading ajax call as you may need to use it more than once i.e On click and scroll.
Hope this helps
To avoid multiple load during fast scroll you can go for this simple approach:
var isLoadingNewPage = false; //initializing the flag
$(document).scroll(function(){
if ($(window).scrollTop() + $(window).height() >= $(document).height())
{
if(!isLoadingNewPage)
{
$('.getmore').click(); //go for next page load
}
}
$('body').on('click','.getmore',function(){
//if the ajax request is going on then don't make another request; simply return back
if(isLoadingNewPage)
return;
var lastelement = $(this ).attr('id');
$.ajax({
type: 'GET',
url: 'getmore.php',
data:'lastelement='+lastelement,
beforesend: function(){
$('.getmore').html('loading....');
isLoadingNewPage = true; //setting the flag so that no more call needed till the time response comes back
},
success: function(data){
$('.getmore').remove();
$('#recs') .append(data) ;
isLoadingNewPage = false; //resetting the flag so that ajax can happen again if user scroll again
}
});
});
});
another approach can be this, put a button at the end of page, so while scrolling you can check if the button is entering in viewport and trigger the click
To avoid to show the same posts everytimes change the getmore ID with the last ID retrieved from ajax call
$.fn.isInViewport = function () {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
if ($('.getmore').isInViewport()) {
$('.getmore').click();
}
$(window).scroll(function(){
if ($('.getmore').isInViewport()) {
$('.getmore').click();
}
$('body').on('click','.getmore',function(){
var lastelement = $(this ).attr('id');
$.ajax({
type : 'GET',
url : 'getmore.php',
data : 'lastelement='+lastelement,
beforesend : function(){
$('.getmore').html('loading....');
},
success: function(data){
/*
to avoid to show the same posts everytimes
change the getmore ID with the last ID retrieved from ajax call
*/
$('.getmore').attr('id', (lastelement + $('.getmore').attr('id')));
$('#recs') .append(data) ;
}
});
});
});
when your ajax response will be empty than you can remove the .getmore button
Such as suggested in other answer introduce a isLoadingNewPage variable is a good practice
I have small angular SPA with couple routes. What I wanted is to have fadein effect only on #/welcome/ page. My jquery works ok but the problem is - its running on all pages and in another pages elements what should be animated just doesnt exist and thats the reason I have errors on my console when user scroll... I tried run script only when route changed and than check if location is /#/welcome but it always running even if not... I tried to put code only to controller which should scoped it to section with animating elements but it also run in another pages... Im confused please help
$scope.$on('$routeChangeSuccess', function() {
if (window.location.hash == '#/welcome') {
function check(element , fadeEffect ) {
$(window).on('scroll' , function(){
var position = $(document).scrollTop() + $(window).innerHeight() ;
var elem = $(element).offset().top + ($(element).innerHeight()) / 2;
if (elem <= position) {
$(element).addClass(fadeEffect);
}
else {
$(element).removeClass(fadeEffect);
}
});
}
check('.tablet' , 'fadeInRight');
check('.padding' , 'fadeInLeft');
}
else {
console.log('another page');
}
});
Your app is SPA, so once you add event to window it will keep until you close the browser tab.
You have to remove the event on destroying welcome page, so remove all those codes and add these to your welcome page controller:
//in welcome page controller
var onScroll = function(){
var queries = [
{elm: '.tablet', effect: 'fadeInRight'},
{elm: '.padding', effect: 'fadeInLeft'}
];
for (var i=0, j=queries.length; i<j; i++) {
var position = $(document).scrollTop() + $(window).innerHeight() ;
var elem = $(queries[i].elm).offset().top + ($(queries[i].elm).innerHeight()) / 2;
if (elem <= position) {
$(queries[i].elm).addClass(queries[i].effect);
}
else {
$(queries[i].elm).removeClass(queries[i].effect);
}
}
}
$(window).on('scroll' , onScroll);
$scope.$on('$destroy', function() {
$(window).off('scroll' , onScroll);
});
Here is the code sample and I its working all perfectly just the case is it loads further ajax request when the scroll bar hits the bottom, I want to make it load when it may reach upto 90% and beyond that form top.
$count = sql::read("SELECT COUNT(table_column_name) as count FROM table_name WHERE Info ='".$info."'");
$actual_row_count = $count[0]->count;
<script type="text/javascript">
$(document).ready(function(e) {
var page = 1;
var flag = 0;
$(window).scroll(function () {
$('#more').hide();
$('#no-more').hide();
if($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
$('#more').css("top","400");
if(flag == 0)
{
$('#more').show();
}
}
if($(window).scrollTop() + $(window).height() == $(document).height()) {
$('#more').hide();
$('#no-more').hide();
page++;
var data = {
page_num: page,
info : '<?php echo $info; ?>'
};
var actual_count = "<?php echo $actual_row_count; ?>";
if((page-1)* 12 > actual_count){
$('#no-more').css("top","400");
$('#no-more').show();
flag = 1 ;
}
else{
$.ajax({
type: "POST",
url: "data.php",
data:data,
success: function(res) {
$("#result").append(res);
console.log(res);
}
});
}
}
});
});
</script>
What you need is to calculate if bottom of current viewport beyond 9/10 of total document height or not. Consider following expression, it might help:
($(window).scrollTop() + $(window).height()) / $(document).height() > 0.9
However, you main problem caused by the fact that scroll event fires multiple time per second. Therefore it make all possible calls before single ajax request has been resolved. You need to unattach event handler before making first call and reattach it after ajax succeed.
For example:
var win = $(window);
function onScroll() {
...
if (90% document scrolled) {
win.off('scroll', onScroll);
$.ajax({
...
success: function(res) {
$("#result").append(res);
win.on('scroll', onScroll);
}
});
}
}
win.on('scroll', onScroll);
So this question is not necessarily how to get it to work, because it does. But it is very very buggy. The problem I'm having is that when you scroll down, it sometimes takes a while to load so that the function reactivates or something. Either way the variable is reset and it loads like 5 pages in a row. So it's buggy. I have the code here:
var ldid = 10;
jQuery(
function ($) {
$('#allpostcontainer').bind('scroll', function () {
if ($(this).scrollTop() +
$(this).innerHeight() >= $(this)[0].scrollHeight) {
$("#allpostcontainer").append($("<div>").load("/streampage.php?id=" + ldid, function () {
ldid = ldid + 10;
}));
}
})
}
);
You can use a flag.
If it is loading you can set it to true.
If loading finished you set it back to false
and you make ajax request only if it is false.
var ldid = 10,
isPageLoading = false;
jQuery(
function ($) {
$('#allpostcontainer').bind('scroll', function () {
if ($(this).scrollTop() +
$(this).innerHeight() >= $(this)[0].scrollHeight && !isPageLoading) {
isPageLoading = true;
$("#allpostcontainer").append($("<div>").load("/streampage.php?id=" + ldid, function () {
ldid = ldid + 10;
isPageLoading = false;
}));
}
})
}
);
If you want to set your Div tag at the end of the "allpostcontainer" div then put below script in your page.
(#bottom is Div tag id which you need to display at the bottom. #allpostcontainer is div tag id which is main Div with scroll)
<script>
$(document).ready(function () {
$('#bottom').css('position', 'absolute');
$('#bottom').css('top', $('#allpostcontainer').height() - $('#bottom').height());
});
</script>
Please let me know if you have any query.
Thank you...
I'm fairly new to jQuery and I'm using the script below. Basically it uses two unordered lists to create tab functionality (one for tabs, one for content). Right now when you click through the tabs, the output is switched from "display:list-item;" to "display:none;". I'm trying to change this to "position:absolute;left:-10000px;" and "position:relative;left:0;" so that all the content gets rendered but just moves off the page rather than be hidden.
I'm having the issue you see at the bottom of the page here http://jqueryui.com/demos/tabs/ except it's not being controlled in the CSS. It's being controlled in the script below somehow that I'm unfamiliar with. Any help would be appreciated.
//INITIALIZATION
$.featureList(
$(".tabs li a"),
$(".output > li"), {
start_item : 0
}
);
//SCRIPT
(function($) {
$.fn.featureList = function(options) {
var tabs = $(this);
var output = $(options.output);
new jQuery.featureList(tabs, output, options);
return this;
};
$.featureList = function(tabs, output, options) {
function slide(nr) {
if (typeof nr == "undefined") {
nr = visible_item + 1;
nr = nr >= total_items ? 0 : nr;
}
tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');
output.stop(true, true).filter(":visible").fadeOut();
output.filter(":eq(" + nr + ")").fadeIn(function() {
visible_item = nr;
});
}
var options = options || {};
var total_items = tabs.length;
var visible_item = options.start_item || 0;
options.pause_on_hover = options.pause_on_hover || true;
options.transition_interval = options.transition_interval || 0;
output.hide().eq( visible_item ).show();
tabs.eq( visible_item ).addClass('current');
tabs.click(function() {
if ($(this).hasClass('current')) {
return false;
}
slide( tabs.index( this) );
});
if (options.transition_interval > 0) {
var timer = setInterval(function () {
slide();
}, options.transition_interval);
if (options.pause_on_hover) {
tabs.mouseenter(function() {
clearInterval( timer );
}).mouseleave(function() {
clearInterval( timer );
timer = setInterval(function () {
slide();
}, options.transition_interval);
});
}
}
};
})(jQuery);
The action in that script is happening with .FadeIn and .Fadeout, which animate opacity. Fadeout applies display:none at the end of the opacity animation. Correspondingly, FadeIn only works on elements that are set to display:none. Fadein just won't work on visibility: hidden or opacity:0. Check out the jquery documentation, it's mostly pretty good.
So you want to substitute a css position change for those two lines of code. There are a bunch of different ways to do this, depending mostly on whether or not you want the elements to animate off the page of just leap there.
Also FYI The easiest way to share this sort of stuff for troubleshooting is to make a jsfiddle with a reduced subset of your code, just the relevant stuff, and then everybody can poke away at it until it works. :)