I have an annoying little issue here. I have code which loads content from page2 and appends it to #content. That works, but sometimes it happens twice, then appends page3 before page2. Thats because in page3, there is just one post, but in page2, 4 posts.
How can I make my code wait until the append finishes to run again? Here's my code:
$(window).scroll(
function(){
if(browserName != "safari") {
var curScrollPos = $('html').scrollTop();
}
else {
var curScrollPos = $('body').scrollTop();
}
if(curScrollPos > 218) {
$("#sidebar").addClass("open");
}
if(curScrollPos < 218) {
$("#sidebar").removeClass("open");
}
var scrollBottom = $(document).height() - $(window).height() - $(window).scrollTop();
if(scrollBottom == 0) {
if(home != 0 || search != 0 || category != 0) {
if(currentPage < numPages) {
$("#main .loader-posts").fadeIn();
currentPage++;
if(search == 1) {
var getPostsUrl = "page/"+currentPage+"/?s="+searchTerm;
}
else {
var getPostsUrl = "page/"+currentPage;
}
$.get(getPostsUrl, function(data) {
$("#main .loader-posts").fadeOut(
'slow',
function(){
var newPosts = $(data).find("#content").html();
$("#content").append(newPosts);
$('#container.tiles').masonry('reload');
});
});
}
}
else {
}
}
Add a variable that keeps track of whether you are loading the next page or not and then only load if you are not currently loading something else. This is the root of your problem. .scroll() may fire twice before the next section is loaded, and as long as currentPage < numPages it will increment currentPage and load again. And, because .get() is asynchronous, you are not guaranteed to finish the first .get() request before any subsequent request. Adding a loading state fixes this.
var loading = 0; // Loading state
if (scrollBottom == 0) {
if (home != 0 || search != 0 || category != 0) {
if (currentPage < numPages && !loading) { // Only proceed if not loading
loading = 1; // We have initiated loading
$("#main .loader-posts").fadeIn();
currentPage++;
if (search == 1) {
var getPostsUrl = "page/" + currentPage + "/?s=" + searchTerm;
} else {
var getPostsUrl = "page/" + currentPage;
}
$.get(getPostsUrl, function(data) {
$("#main .loader-posts").fadeOut('slow', function() {
var newPosts = $(data).find("#content").html();
$("#content").append(newPosts);
$('#container.tiles').masonry('reload');
loading = 0; // We are done loading
});
});
}
} else {
}
}
Maybe you can add an isBusy flag that you can check before the $.get(), and set it to false in the $.get() callback?
Related
I've got a carousel in this webpage https://stfn.herokuapp.com and It works almost perfect, only the main (active) item, which is in the center, Doesn't do anything once it's clicked (it's supposed to redirect) I tried to add the link both in js file and in the index, but didn't solve the problem anyone got tips?
[edit]
Forgot to upload the latest build before asking the question, just did it. So I added an a tag to the img in the index.html, and that doesn't seem to work either. Here's a snippet of code for redirecting from the js file
$('.carousel .item').click(function(e) {
var index = $(this).index('li');
carousel.cycleActiveTo(index);
// song3();
e.preventDefault();
if ( currentIndex != index ){
var difference;
if ( currentIndex == 0 && index >= 5 ){
difference = (index - currentIndex) - 13;
} else {
difference = index - currentIndex;
}
difference = Math.abs(difference);
delay = difference * options.duration;
currentIndex = index;
console.log(delay);
setTimeout( goToLink, delay );
}
});
goToLink = function() {
if (currentIndex == 0) {
// console.log("works:");
document.location.href = "about.html"
}
if (currentIndex == 1) {
document.location.href = "blog.html"
}
else if (currentIndex == 2) {
document.location.href = "collection.html"
}
else if (currentIndex == 3) {
document.location.href = "shop.html"
}
else if (currentIndex == 4) {
// alert("ABOUT2");
document.location.href = "about.html"
}
else if (currentIndex == 5) {
document.location.href = "blog.html"
}
else if (currentIndex == 6) {
document.location.href = "collection.html"
}
else if (currentIndex == 7) {
document.location.href = "contact.html"
}
else if (currentIndex == 8) {
document.location.href = "shop.html"
}
else if (currentIndex == 9) {
document.location.href = "contact.html"
}
else if (currentIndex == 0) {
document.location.href = "about.html"
}
}
});
So as you see, every element has an index assigned to it, and it allows to switch to a specific page. The active item has the index number 0, however it doesn't seem to work like the others
if ( currentIndex != index ){ <-- this check is false since both are zero.
So if the check is equal it does nothing
You need an else and call the goto method.
if ( currentIndex != index ){
... the code ...
} else {
goToLink();
}
I was working on a project that, when you click the page, it scrolls the entire length of the page. But it does this at 20px intervals; this is to allow javascript to be executed while scrolling in iOS.
However, when uploading the final version, my ftp client has deleted some of the code and it's now not working. I can't see why.
Any suggestions?
var t;
var scrolling = false;
// doScroll sets the position in which to auto pause.
function doScroll() {
$('body').scrollTop($('body').scrollTop() + 20);
if($("#pause").offset().top >=300 && $("#pause").offset().top < 304){
ScrollIt();
} else
if($("#pause").offset().top >=4000 && $("#pause").offset().top < 4004){
ScrollIt() ;
} else
if($("#pause").offset().top >=7500 && $("#pause").offset().top < 7504){
ScrollIt() ;
}
}
// ScrollIt removes the interval for scrolling, pausing the scroll.
function ScrollIt() {
clearInterval(t);
scrolling = false;
return;
// playPause()
}
//Stop/start on click
$('#pause').on('click',function(){
ScrollIt();
scrolling = !scrolling;
if(!scrolling){
clearInterval(t);
return;
}
t = setInterval(doScroll, 5);
});
I create jsfiddle page for you.
http://jsfiddle.net/u32Nw/2/
I can see that it is working, but scrolling is not stopping.
var t;
var scrolling = false;
// doScroll sets the position in which to auto pause.
function doScroll() {
var $body = $("body"),
$pause = $("#pause");
$body.scrollTop($body.scrollTop() + 20);
var pauseTop = $pause.offset().top;
if (pauseTop >= 300 && pauseTop < 304 || pauseTop >= 4000 && pauseTop < 4004 || pauseTop >= 7500 && pauseTop < 7504) {
clearScrollInterval();
}
}
// scrollIt removes the interval for scrolling, pausing the scroll.
function clearScrollInterval() {
clearInterval(t);
scrolling = false;
return;
// playPause()
}
//Stop/start on click
$("#pause").on("click", function () {
clearScrollInterval();
scrolling = !scrolling;
t = setInterval(doScroll, 5);
});
This is exact same code, just refactored.
Try working from here. You need to refactor your code for debugging.
I am developing iPad application in that more than 6 iframes are available. After fully loaded the page, the page scroll went to the some where in the middle. So I decided to get page scrolltop written JavaScript code like this:
$(document).ready(function() {
try {
var iframecompleted = [];
$("iframe[id*='iframe']").each(function(eli, el) {
$(this).bind("load", iframeinit);
});
function iframeinit() {
iframecompleted.push($(this).id);
$(this).unbind("load", iframeinit);
}
var timer = setInterval(function() {
if ($("iframe[id*='iframe']").length == iframecompleted.length) {
clearInterval(timer);
$('html, body').animate({
scrollTop: 0
}, 500);
if (FrameID != "") {
var j = 0;
var ss = FrameID.split(",")
for (j = 0; j < ss.length; j++) {
var collPanel = $find("pane" + ss[j]);
if (collPanel != null)
collPanel.set_Collapsed(true);
}
FrameID = "";
}
}
}, 10);
}
catch (e) {
alert(e);
}
});
}
I would like to find a better way to achieve this task. Your ideas are more welcome.
You could do something like this :
var count = 0;
$("iframe").load(function() {
if (++count === 6)
{
alert("TODO: All the frames are loaded, do you stuff");
}
});
http://jsfiddle.net/eDVEY/
You can do something like this:
var count = $('iframe').length;
$(function() {
$('iframe').load(function() {
count--;
if (count == 0)
alert('all frames loaded');
});
});
Hope it helps
I wrote this javascript to make an animation. It is working fine in the home page. I wrote a alert message in the last.
If I go other then home page, this alert message has to come, but I am getting alert message, if I remove the function, alert message working on all pages, any thing wrong in my code?
window.onload = function(){
var yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
var signUp = document.getElementById('signup-link');
if (yellows != 'undefined' && signUp != undefined){
function animeYellowBar(num){
setTimeout(function(){
yellows[num].style.left = "0";
if(num == yellows.length-1){
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},num*250);
}
}, num * 500);
}
for (var i = 0; i < yellows.length; i++){
animeYellowBar(i);
}
}
alert('hi');
}
DEMO: http://jsbin.com/enaqu5/2
var yellows,signUp;
window.onload = function() {
yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
signUp = document.getElementById('signup-link');
if (yellows !== undefined && signUp !== undefined) {
for (var i = 0; i < yellows.length; i++) {
animeYellowBar(i);
}
}
alert('hi')
}
function animeYellowBar(num) {
setTimeout(function() {
yellows[num].style.left = "0";
if (num == yellows.length - 1) {
setTimeout(function() {
signUp.style.webkitTransform = "scale(1)";
},
num * 250);
}
},
num * 500);
}
DEMO 2: http://jsbin.com/utixi4 (just for sake)
$(function() {
$("#magazine-brief h2").each(function(i,item) {
$(this).delay(i+'00').animate({'marginLeft': 0 }, 500 ,function(){
if ( i === ( $('#magazine-brief h2').length - 1 ) )
$('#signup-link')[0].style.webkitTransform = "rotate(-2deg)";
});
});
});
For starters you are not clearing your SetTimeout and what are you truly after here? You have 2 anonymous methods that one triggers after half a second and the other triggers a quarter of a second later.
So this is just 2 delayed function calls with horribly broken syntax.
Edited Two possibilities, one fixes your current code... the latter shows you how to do it using JQuery which I would recomend:
var yellows, signUp;
window.onload = function(){
yellows = document.getElementById('magazine-brief');
if(yellows != null){
yellows = yellows.getElementsByTagName('h2');
}else{
yellows = null;
}
signUp = document.getElementById('signup-link');
if (yellows != null && signUp != null && yellows.length > 0)
{
for(var i = 0; i < yellows.length; i++)
{
animeYellowBar(i);
}
}
alert('hi');
}
function animeYellowBar(num)
{
setTimeout(function(){
yellows[num].style.left = "0";
if(num == yellows.length-1){
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},num*250);
}
}, num * 500);
}
The below approach is a SUMMARY of how to use JQuery, if you want to use JQuery I'll actually test it out:
//Or using JQuery
//Onload equivelent
$(function(){
var iterCount = 0,
maxIter = $("#magazine-brief").filter("h2").length;
$("#magazine-brief").filter("h2").each(function(){
setTimeout(function(){
$(this).css({left: 0});
if(iterCount == (maxIter-1))
{
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},iterCount*250);
}
}, iterCount++ * num );
});
});
I'm having some issues with this. For some reason, updateCurrentItem is always called with the same parameter regardless.
function updatePromoList(query) {
query = query.toUpperCase();
clearCurrentList();
var numItems = 0;
currentItem = 0;
result_set = cached[query.charAt(0)][query.charAt(1)][query.charAt(2)];
for(i in result_set){
if(numItems >= NUMBER_MATCHES){
$("<li/>").html("<span style='color: #aaa'>Please try to limit your search results</span>").appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(numItems+1); });
break;
}
promo = result_set[i];
found_number = false;
if (!promo.client)
found_number = (promo.prj_number.toString().substr(0,query.length) == query) ? true : false;
if (query.length >= MATCH_NAME) {
if(promo.prj_name && typeof promo.prj_name == 'string'){
found_name = promo.prj_name.toUpperCase().indexOf(query);
} else {
found_name = -1;
}
if (promo.client)
found_client = promo.client_name.toString().indexOf(query);
else
found_client = -1;
} else {
found_name = -1;
found_client = -1;
}
if(found_client >= 0) {
var thisIndex = numItems+1;
console.log("setting", thisIndex);
$("<li/>").text(promo.client_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); }); } else if(found_name >= 0 || found_number) { var thisIndex = numItems+1;
console.log("setting", thisIndex);
$("<li/>").text(promo.prj_number+": "+promo.prj_name).bind('click',function(e){ updatePromoChoice(e,promo); }).appendTo("#possibilities").mouseover(function(event){ updateCurrentItem(thisIndex); });
}
if(found_number || found_client >= 0 || found_name >= 0){
numItems++;
}
}
}
function updateCurrentItem(i){
currentItem = i;
console.log("updating to", i);
}
The results of running this are:
setting 0
setting 1
setting 2
setting 3
setting 4
setting 5
setting 6
setting 7
setting 8
setting 9
setting 10
setting 11
setting 12
setting 13
then when I move my mouse over the content area containing these <li>s with the mouseOver events, all I ever see is:
updating to 4
Always 4. Any ideas?
You're creating a closure but it's still bound to the numItems variable:
function(event){ updateCurrentItem(numItems+1); }
What you should do is something like this:
(function(numItems){return function(event){ updateCurrentItem(numItems+1); }})(numItems)
Edit: I think I might have the wrong function but the same principle applies:
function(event){ updateCurrentItem(thisIndex); }
should be
(function(thisIndex)
{
return function(event){ updateCurrentItem(thisIndex); }
})(thisIndex)