jQuery How to Have Variable Increment by Value in a Recursive Function - javascript

I have a JS Function which is called in document.ready. The intent is as it scrolls to the bottom window, it'll load more from the JSON API.
The API has the parameter offset and limit. Offset controls which subset of results you are seeing. For ex. 20-40 would be offset=20 and limit controls how many you can view at once.
I thought I would approach this with a recursive function which calls itself each time the user goes to the bottom of the window, with window.scroll. Once they go to the bottom, it'll increment the offset by 20 each time, then run the function again.
Problem: I can't seem to get it to increment the variable by 20 to make this work. Thoughts?
function getData(offset) {
var jsonCallback = "&jsoncallback=?";
//var offset = 20;
//var offset += 20;
var limit = 20;
var characterURL = "http://api.example.com/character&byId=" + characterID + "&offset=" + offset + "&limit=" + limit;
$.getJSON(characterURL + jsonCallback, function(data) {
for (i=0; i < (data.data.results).length; i++) {
var $characterUl = $("<ul>");
$characterUl.appendTo("#characterComics");
$("<li>").text(data.data.results[i].title).appendTo($characterUl);
$("<li>").text(data.data.results[i].id).appendTo($characterUl);
$("<li>").text(data.data.results[i].release_date).appendTo($characterUl);
if (data.data.results[i].release_date > 0) {
$characterLi.text(data.data.results[i].issue_number).appendTo($characterUl);
}
}
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 10) {
while ((data.data.results).length === offset || (data.data.results).length > offset) {
offset = offset+20;
$("<div>").text(offset).appendTo("body");
getComics(offset);
}
}
});
});
}
$(document).ready(function() {
var $characterComics = $("<div>", {id : "characterComics"});
$characterComics.appendTo("body");
getData(0);
});

UPDATED
Read this more as a pseudo-code
function getData(offset) {
var jsonCallback = "&jsoncallback=?",
characterURL = "http://api.example.com/character&byId=" + characterID + "&offset=" + offset + "&limit=" + limit;
$.getJSON(characterURL + jsonCallback, function(data) {
for (i=0; i < (data.data.results).length; i++) {
var $listItem = $("<li>");
listItem.append("<span>"+data.data.results[i].title+"</span>");
listItem.append("<span>"+data.data.results[i].id+"</span>");
listItem.append("<span>"+data.data.results[i].release_date+"</span>");
if (data.data.results[i].release_date > 0) {
listItem.append("<span>"+data.data.results[i].issue_number+"</span>");
}
listItem.appendTo($characterUl);
itemsLoaded++;
}
});
}
$(document).ready(function() {
var $characterComics = $("<div>", {id : "characterComics"}),
$characterUl = $("<ul>"),
offset = 0,
itemsLoaded = 0;
limit = 20;
$characterComics.appendTo("body");
$characterUl.appendTo($characterComics);
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 10) {
if ("check here if you reached your offsets") {
offset = offset+20;
getData(offset);
}
}
});
// get your first set of data
getData(0);
});

Related

jQuery Won't Run On IE nor does normal JS

After creating a snippet of code using jQuery, making sure it works on chrome, I tested it out on IE and I realised that none of the jQuery code is running in it. I tried to fix this issue by changing all the jQuery to Pure JS. And still, I get no results. Is anyone here can help me understand why IE is so out of the loop and how I can fix this issue. It's for a client and they are using IE.
So the code is:
let Section5Run = true;
const myServices = $('.service-link');
function ServiceSlideIn(services, index = 0) {
if (services.length -1 < index) { return; }
$(services[index]).css('transform', 'translateX(0%)');
console.log("Section 5 occurance " + index);
setTimeout(ServiceSlideIn, 500 , services, ++index);
}
//On Load Page
$(document).ready(function() {
//When Window Is Scrolled
$(window).scroll( function(){
const MSOFFSET = $('.service-link')[0].clientHeight/2;
var bottom_of_object = $('#section-5-box').offset().top + MSOFFSET;
var bottom_of_window = $(window).scrollTop() + $(window).height();
if( bottom_of_window > bottom_of_object && Section5Run ){
Section5Run = false;
ServiceSlideIn(myServices);
}
});
});
Then it was converted to this:
function ServiceSlideIn(services, index = 0) {
if (services.length -1 < index) { return; }
services[index].style.transform = "translateX(0%)";
console.log("Section 5 occurance " + index);
setTimeout(ServiceSlideIn, 500 , services, ++index);
}
var cond = true;
document.addEventListener("scroll", function () {
var wind = window.scrollY;
var sec_5 = document.getElementById("section-5-box");
var items = document.getElementsByClassName("service-link");
var sec_off = offset(sec_5).top;
console.log("rest");
if (wind + (sec_5.clientHeight * 1.5) > sec_off && cond){
console.log("Clients's top: " + sec_off);
console.log("Client's Height is " + sec_5.clientHeight);
console.log("Window's height: " + (wind + sec_5.clientHeight/3));
console.log("items Length " + items.length);
ServiceSlideIn(items);
cond= false;
}
});
function offset(el) {
var rect = el.getBoundingClientRect(),
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
}
Pretty basic slide animation done here.
Please do check the website for yourself cubeangle.com under Our Services the boxes will slide in right to left.
Thank you all.

jQuery slider doesn't rotate

I have a slider rotator on my site but it doesn't rotate items automatically in the boxes - navigation works and rotate but I want it to rotate automatically, right after I enter the site.
This is my js:
$(document).ready(function() {
var nbr = 0;
$('.slider').each(function() {
var slider = $(this);
//get width and height of the wrapper and give it to the UL
var wrapperwidth = $(slider).width() * $(slider).find('ul > li').size();
$(slider).find('ul').css('width', wrapperwidth);
var wrapperheight = $(slider).height();
$(slider).find('ul').css('height', wrapperheight);
//set my li width
var width = $(slider).width();
$(slider).find('ul li').css('width', width);
//set my counter vars
var counter = $(slider).find('ul > li').size();
var decount = 1;
var autocount = 1;
if (counter > 1) {
//create my number navigation
var createNum = 1;
$(slider).after('<ul class="numbers"><li></li></ul>');
var numbers = $(slider).parent().find('.numbers');
$(numbers).find('li:first-child').html(createNum+'_'+nbr).addClass('activenum').attr('id', 'id1_'+nbr);
while ( createNum != counter) {
createNum++;
$(numbers).append("<li id='id"+createNum+"_"+nbr+"'>"+createNum+"_"+nbr+"</li>");
}
//get my number-width (number navigation should always be centered)
var numwidth = $(slider).find('.numbers li:first-child').width() * $(slider).find('.numbers li').size();
$(slider).find('.numbers').css('width', numwidth);
}
nbr++;
});
//make the number clickable
$(".numbers li").click(function() {
var slider = $(this).closest('.sliderWrapper');
var slider0 = $(slider).find('.slider');
var clickednum = $(this).html().split('_')[0] * - $(slider0).width() + $(slider0).width();
$(slider0).find('ul').animate({ left: clickednum }, 400, 'swing', function() { });
$(slider).find('.activenum').removeClass('activenum');
$(this).addClass('activenum');
decount = $(this).html();
});
rotateSwitch = function(sliderW, speed) {
var sliderWrap = sliderW;
play = setInterval(function() {
var nextNum = parseInt($($(sliderWrap).find(".numbers li.activenum")).html().split('_')[0])+1;
if (nextNum > $(sliderWrap).find(".numbers li").length) {
nextNum = 1;
}
//console.log("nextnum: "+nextNum+", numbers length: "+$(sliderWrap).find(".numbers li").length);
$(sliderWrap).find(".numbers li").each(function() {
if( parseInt($(this).html().split('_')[0]) == nextNum )
$(this).click();
});
}, speed);
};
makeAutoSlide = function(sliderWrap, speed) {
if ($(sliderWrap).length > 0 && $(sliderWrap).find(".numbers li").length > 1) {
rotateSwitch(sliderWrap, speed);
$(sliderWrap).find(".slider li").hover(function() {
if ($(sliderWrap).find(".numbers li").length > 1) {
clearInterval(play); //Stop the rotation
}
}, function() {
if ($(sliderWrap).find(".numbers li").length > 1) {
rotateSwitch(sliderWrap, speed); //Resume rotation timer
}
});
}
};
});
I'm not really sure if this is a problem with setInterval and clearInterval or I wrote something wrong.
I put code in jsFiddle, so you know how the structure looks like.
http://jsfiddle.net/gecbjerd/1/
I appreciate for help.
Cheers

Javascript how to set interval time to stop scrolling

This is the demo in jsfiddle, demo
What I want is let the scrolled items('one ', 'two', 'three', '4', '5', '6', '7') automatically scroll up like the demo showed, and stop 2 sec when it's in the middle position. But in my demo, it will shack for a while after stopping in the middle position.
Here is the place in my demo code for setting position.
if ((x == 0) || (x % 35== 0)) {
setTimeout(function () {
i.top = x + 'px';
}, 1000);
} else {
i.top = x + 'px';
}
Any one can help me? Thanks!
UPDATE:
The reason why I set 35 is because I found that the scrolled items are approximately in the middle position when it equals to 0, -35,-70,-105,.... But when I console all x, I found that the value of x is between (31, -251). Do you know how to find the exact position when each items are in the middle of position? Thanks!
i modified your code a bit,
i set a variable "k" that the interval is assigned to and i clear the interval on stop and start it again after the timeout
looks good for me -> http://jsfiddle.net/ato0mf7u/3/
no funny shakin anymore ;-D
window.onload = addScrollers;
var i = 1;
var arr = ['one ', 'two', 'three', '4', '5', '6', '7'];
var mid;
var k;
function addScrollers() {
var txt = arr[0];
while (i < arr.length) {
txt += '<p>' + arr[i] + '</p>';
i++;
}
startScroll('myscroller', txt);
}
var speed = 10; // scroll speed (bigger = faster)
var dR = false; // reverse direction
var step = 1;
function objWidth(obj) {
if (obj.offsetWidth) return obj.offsetWidth;
if (obj.clip) return obj.clip.width;
return 0;
}
function objHeight(obj) {
if (obj.offsetHeight) return obj.offsetHeight;
if (obj.clip) return obj.clip.height;
return 0;
}
function scrF(i, sH, eH) {
var x = parseInt(i.top) + (dR ? step : -step);
if (dR && x > sH) {
x = -eH;
} else if (x < 1 - eH) {
x = sH;
}
//when x is the times of 35, the positio is in middle
if ((x == 0) || (x % 35== 0)) {
clearInterval(k);
setTimeout(function () {
i.top = x + 'px';
k = setInterval(function () {
scrF(i, sH, eH);
}, 1000 / speed);
}, 1000);
}
else {
i.top = x + 'px';
}
return x;
}
function startScroll(sN, txt) {
var scr = document.getElementById(sN);
var sW = objWidth(scr);
var sH = objHeight(scr);
scr.innerHTML = '<div id="' + sN + 'in" style="position:absolute; left:3px; width:' + sW + ';">' + txt + '<\/div>';
var sTxt = document.getElementById(sN + 'in');
var eH = objHeight(sTxt);
mid = (eH - sH) / 2;
sTxt.style.top = (dR ? -eH : sH) + 'px';
sTxt.style.clip = 'rect(0,' + sW + 'px,' + eH + 'px,0)';
k = setInterval(function () {
scrF(sTxt.style, sH, eH);
}, 1000 / speed);
}

DIV animation and property change

I'm trying to simulate TCP packet transmission and sliding window, and fortunately I've made much progress. But now I want to fix a minor issue with the sliding window, which is a sliding DIV:
Hopefully if you are familiar with TCP's slow start, the window size double up to a number, and then increments by one. This is working. Now what I want to fix is sliding to right. So I want to automatically slide one step right when each ack is received at the original machine. Currently it does not move when the ack is received; so each time I press the button, it retransmits many of the previous packets! My work is here: http://web.engr.illinois.edu/~shossen2/CS438/Project/
$(document).ready(function () {
var count = 0;
var items = 0;
var packetNumber = 0;
var speed = 0;
var ssth= $("#ssth").val();
var window_left=0;
for (var i = 1; i <= 32; i++) {
$('#table').append("<div class='inline' id='"+i+"'>"+i+"</div>");
}
document.getElementById(1).style.width = 22;
$("button").click(function() {
if (items < ssth) {
if (items == 0)
items = 1;
else
items = items * 2;
count++;
} else {
items = items + 1;
}
window_left += 20;
window_width=items * 20;
document.getElementById("window_size").innerHTML = items;
document.getElementById("window").style.left= window_left + "px";
document.getElementById("window").style.width=window_width + "px";
speed = +$("#speed").val();
createDivs(items);
animateDivs();
});
function createDivs(divs) {
packetNumber = 1;
var left = 60;
for (var i = 0; i < divs; i++) {
var div = $("<div class='t'></div>");
div.appendTo(".packets");
$("<font class='span'>" + (parseInt(packetNumber) + parseInt(window_left/20) -1) + "</font>").appendTo(div);
packetNumber++;
div.css({
left: left
/* opacity: 0*/
}).fadeOut(0);
//div.hide();
//left += 20;
}
}
function animateDivs() {
$(".t").each(function (index) { // added the index parameter
var packet = $(this);
packet
.delay(index * 200)
.fadeIn(200, function() {
$('#table #' + (index + window_left/20)).css({background:'yellow'});
})
.animate({left: '+=230px'}, speed)
.animate({left: '+=230px'}, speed)
.fadeOut(200, function () {
packet
.css({
top: '+=20px',
backgroundColor: "#f09090"
})
.text('a' + packet.text());
})
.delay(500)
.fadeIn(200)
.animate({left:'-=230px'}, speed)
.animate({left:'-=230px'}, speed)
.fadeOut(200, function () {
packet
.css({
top: '-=20px',
backgroundColor: "#90f090"
});
$('#table #' + (index + window_left/20)).css({background:'lightgreen'});
});
}).promise().done(function(){
$(".packets").empty();
});
}
});

Having issues with live calculations, calculating each key stroke

I have a table that calculates a total depending on the input the user types. My problem is that the jquery code is calculating each key stroke and not "grabbing" the entire number once you stop typing. Code is below, any help woud be greatly appreciated.
$(document).ready(function() {
$('input.refreshButton').bind('click', EstimateTotal);
$('input.seatNumber').bind('keypress', EstimateTotal);
$('input.seatNumber').bind('change', EstimateTotal);
});
//$('input[type=submit]').live('click', function() {
function EstimateTotal(event) {
var tierSelected = $(this).attr('data-year');
var numberSeats = Math.floor($('#numberSeats_' + tierSelected).val());
$('.alertbox_error_' + tierSelected).hide();
if (isNaN(numberSeats) || numberSeats == 0) {
$('.alertbox_error_' + tierSelected).show();
} else {
$('.alertbox_error_' + tierSelected).hide();
var seatHigh = 0;
var seatLow = 0;
var seatBase = 0;
var yearTotal = 0;
var totalsArray = [];
var currentYear = 0;
$('.tier_' + tierSelected).each(function() {
seatLow = $(this).attr('data-seat_low');
firstSeatLow = $(this).attr('data-first_seat_low');
seatHigh = $(this).attr('data-seat_high');
seatBase = $(this).attr('data-base_cost');
costPerSeat = $(this).attr('data-cost_per_seat');
years = $(this).attr('data-year');
seats = 0;
if (years != currentYear) {
if (currentYear > 0) {
totalsArray[currentYear] = yearTotal;
}
currentYear = years;
yearTotal = 0;
}
if (numberSeats >= seatHigh) {
seats = Math.floor(seatHigh - seatLow + 1);
} else if (numberSeats >= seatLow) {
seats = Math.floor(numberSeats - seatLow + 1);
}
if (seats < 0) {
seats = 0;
}
yearTotal += Math.floor(costPerSeat) * Math.floor(seats) * Math.floor(years) + Math.floor(seatBase);
});
totalsArray[currentYear] = yearTotal;
totalsArray.forEach(function(item, key) {
if (item > 1000000) {
$('.totalCost_' + tierSelected + '[data-year="' + key + '"]').append('Contact Us');
} else {
$('.totalCost_' + tierSelected + '[data-year="' + key + '"]').append('$' + item);
}
});
}
}
You'll need a setTimeout, and a way to kill/reset it on the keypress.
I'd personally do something like this:
var calc_delay;
$(document).ready(function() {
$('input.refreshButton').bind('click', runEstimateTotal);
$('input.seatNumber').bind('keypress', runEstimateTotal);
$('input.seatNumber').bind('change', runEstimateTotal);
});
function runEstimateTotal(){
clearTimeout(calc_delay);
calc_delay = setTimeout(function(){ EstimateTotal(); }, 100);
}
function EstimateTotal() {
....
What this does is prompt the system to calculate 100ms after every keypress - unless another event is detected (i.e. runEstimateTotal is called), in which case the delay countdown resets.

Categories