How can I "kill" this setTimout function but not to break my code?
I tried with clear and it didn't work.
For some reason when I delete it everywhere it breaks my code (also if i remove this function evertwhere).
When I say "return" on the top before timeout executes my jQuery shows up but my code doesn't work.
To mention also my jQuery file loads in Mozilla. It also loads on my local machine in Chrome and Safari, but not in live on the server( im also using Wordpress) Safari/Chrome.
Function with the setTimeout
function queueRender() {
var _this = this;
settings.queueRenderTimeout = setTimeout(function(){
render();
}, settings.debounce);
if(typeof settings.queueRenderTimeout !== "undefined") {
clearTimeout(settings.queueRenderTimeout)
}
render();
}
Here is render function
function render() {
element.find(">").remove();
var t = templates.quiz(quiz);
element.append(t);
$(settings.append).append(element);
}
-- so in this case, my jQuery loads, but my quiz breaks.
if i change the order and put first IF statement then my code doesnt break.
Here is my settings:
var defaults = {
append: "body",
quiz_template: "#quiz_template",
question_template: "#question_template",
answer_template: "#answer_template",
result_template: "#result_template",
shuffle: true
// debounce: 10
}
Code is something working sometimes don't. It works on my local machine, but not on the server. I feel like there is still some delay from the setTimout even when I leave it "undefined".
Related
I am creating tests for a page and HAVE to use jQuery to change elements on the control version of the page for each different experience.
I'm using jquery to load an element from an external page and replace a div. However, on the external page, it uses an ajax call to an api to populate the div, so I copied over the function with the ajax call.
I think it is attempting to make the ajax call before the new div is actually loaded on the page.
I've tried moving the function, wrapping the load function within the ajax call, but it still doesnt work.
I could be missing something obvious, but here's that part of my code:
$('.replace-div').load('external.html #replace-div');
function waitForLoad() {
if ($('#replace-div')) {
var object;
$.ajax({
url: "https://api.com",
async: false,
success: function(result) {
object = result;
var variable1 = object["blah"][0].value,
var variable2 = object["blah"][0].value,
var variable3 = object["blah"][0].value,
var variable4 = object["blah"][0].value,
$('newElement').attr('href', variable1);
$('newElement2').attr('src', variable2);
$('newElement3').attr('href', variable3);
$('newElement4').text("text" + variable4 + "more text");
}
});
} else {
setTimeout(waitForLoad, 15);
}
}
waitForLoad();
I don't get any errors in the console, and when I paste the above waitForLoad function into the console, it populates totally fine. obviously this is after the page loads the new div, so i just need to know how to make the ajax call wait for the load.
I've tried .ajaxComplete(), but it doesnt help.
$(function() {}); also does not work
.load() has a callback argument where you supply a function to run after the data is loaded.
$('replace-div').load('external.html #replace-div', function() {
$.ajax(...);
});
So, what happens is that, once waitForLoad is called for the first time, it doesn't see the div loaded, the code goes to the else block and executes again with a 15ms timeout. 15ms is not enough for the div to load, most likely.
You can try three things (ordered from worse to better):
Try increasing the timeout to a bigger number. Start with 1000 (1000ms - 1 second) and see if it works or you need to increase it. It's more likely you'll have to decrease it
Try using setInterval instead of setTimeout, which will repeat itself. Of course, once it loads, you'll need to clear the interval so it stops. Also, better use bigger timeouts/intervals, like 50 or 100ms b/c the fast firing timers can slow down a page a lot
E.g.
$('.replace-div').load('external.html #replace-div');
function waitForLoad() {
if ($('#replace-div')) {
clearInterval(window.waiter);
...
} else {
window.timer = setInterval(waitForLoad, 50);
}
}
waitForLoad();
Same as 2, but using more idiomatic callback function after load call.
// the window.waiter is the interval handle, and it will run every 100ms. It calls .load every time, and if the #replace-div is found, unsets the interval handle.
window.waiter = setInterval(function() {
$(".replace-div").load("external.html #replace-div", function() {
if ($(".replace-div #replace-div").length) {
// found the DIV
// code...
clearInterval(window.waiter); // bye interval handle, thanks
}
});
}, 100);
I am having some trouble wrapping my head around this. I have a web application that is almost entirely built with javascript. It starts out with a basic template, then starts adding content to it as the user interacts. I am trying to use Greensock as the animation library which has the ability to use a progress slider to show how far you are in the animation, see the second box here: https://greensock.com/timelinemax
The issue is that it uses a callback onUpdate that is supposed to run that function on each frame. Then I can use it to make the slider track with the animation.
var mainTL = new TimelineLite({onUpdate:updateSlider});
function updateSlider() {
sliderTimeline.noUiSlider.set( mainTL.progress());
}
This would work - except that the slider object doesn't exist yet. I don't know why, this is some of the last code to be included in the file, but I get a couple errors in the console log just loading the page `ReferenceError: sliderTimeline is not defined' but then everything works.
To try getting away from those errors, I tried to do it like this:
var mainTL = new TimelineLite({onUpdate:updateSlider});
$( document ).ready(function() {
function updateSlider() {
sliderTimeline.noUiSlider.set( mainTL.progress());
}
});
except now it fails because the updateSlider' function hasn't been defined, and it fails to start at all. I could put them both in a$( document ).ready(function()`, but then they become local functions / variables and the 5 other javascript files I am working with don't have access to them.
Do I have to live with the errors, or is there something I am not thinking of?
You can check whether sliderTimeline exists before trying to call it. For example change function updateSlider() to:
function updateSlider() {
if (typeof sliderTimeline !== 'undefined') {
sliderTimeline.noUiSlider.set( mainTL.progress());
}
}
Or if you know that sliderTimeline is declared, but not assigned yet:
function updateSlider() {
if (sliderTimeline) {
sliderTimeline.noUiSlider.set( mainTL.progress());
}
}
Note that this works because onUpdate is called frequently, so it will eventually be called when sliderTimeline is eventually defined.
Edit:
Additionally, you can assign global variables inside $( document ).ready() as long as you declare them outside of the function.
For example:
var mainTL;
var updateSlider;
$( document ).ready(function() {
updateSlider = function () {
sliderTimeline.noUiSlider.set( mainTL.progress());
};
mainTL = new TimelineLite({onUpdate: updateSlider});
});
If you look at their codepen page http://codepen.io/GreenSock/pen/FnsqC/ they have:
var tl = new TimelineMax({delay:0.5, repeat:3,
repeatDelay:2, onUpdate:updateStats,
onRepeat:updateReps, onComplete:restart});
function updateReps() {
reps++;
repeatCount.innerHTML = reps;
}
function updateStats() {
time.innerHTML = tl.time().toFixed(2);
totalTime.innerHTML = tl.totalTime().toFixed(2);
progress.innerHTML = tl.progress().toFixed(2);
totalProgress.innerHTML = tl.totalProgress().toFixed(2);
}
Meaning that you need to define the callback function of onUpdate.
I am currently working on a data-intensive web application that frequently communicates with an external API and retrieves JSONP data when returned. The script depends upon a library called head.js v1.0.3. http://headjs.com/ to accomplish this. However, I noticed that in IE 11 for some reason, the onload event for the script sometimes, but not always, fires before the script has actually loaded into the browser. The behavior is demonstrable whether using head.js or not. Alternatively, I may create a script element with the onload event set to capture the returned data. Sometimes it works, and sometimes not. Even more weird is that once it happens the first time, it seems to keep happening for the duration of the browser session.
Any ideas for a workaround?
Here is some example code:
//somejson.js
/*
window["queryResult"] = {blah:'blah'}
*/
function loadScript() {
head.load("/somejson.js", afterScriptLoad)
}
function afterScriptLoad() {
var result = queryResult
//Throws error because window.queryResult is sometimes undefined
}
After a little bit of research, it seems the only way around this bug is to modify the API so that once the variable holding the JSONP is initialized, the script itself triggers the callback. Unfortunately, this would not work as a solution for others if they do not have access to modify whatever API is in use, but it does solve the problem for me.
//somejson.js
/*
window["queryResult"] = {blah:'blah'}; scriptCallback()
*/
function loadScript(callback) {
var c = new afterScriptLoad(callback)
window["scriptCallback"] = c
head.load("/somejson.js", c)
}
function afterScriptLoad(callback) {
var retrieved = false
return function () {
if (!retrieved) {
retrieved = true
callback(queryResult)
}
}
}
function myCallback(response) {
//do something
}
i have a locate function defined in javascript
var locID;
function locateMe()
{
if(locID > 0)
{
// i do a jquery post here
}
setTimeout(locateMe, 2000);
}
// my document ready function is here, and inside it, at the end of it
// i do this
locID = 0;
locateMe();
when i test this code in firefox, the locateMe function is called every two seconds and works as expected. when i test the code in IE8 the function is never called (at least it appears to never be called from what i can see using IE's developer tools)
note: there is code defined in a click event handler for the 'zone_row' class that modifies locID. again, in firefox everything works as expected. the strange thing is, in IE when a zone_row is clicked the function WILL be called ONCE. i can see that both on the developer tools and through the result of the action of that jquery post.
i figured there is just some anomly with IE that i am not familiar with yet. what am i doing wrong?
EDIT: changed "locateMe();" to locateMe inside the setTimeout call.
UPDATE: adding more of my code (per request in comments) to show placement (albeit not much more code than my first post).
<script type="text/javascript">
var z_items;
var locID;
function locateMe()
{
if(locID > 0)
{
// my jquery post is here
}
setTimeout(locateMe, 2000);
}
$(document).ready(function()
{
// ... some click events and get requests here ...
locID = 0;
locateMe();
});
</script>
i also tried wrapping the call in a setTimeout (no effect) and changing the DOCTYPE (this actually caused IE to never call the function as opposed to now where it calls it ONCE and never again).
problem solved. i found an answer to another problem i was having from this post:
Prevent browser caching of jQuery AJAX call result
upon adding $.ajaxSetup({ cache: false }); to my document ready function, it solved THIS problem too. it looks like all this time it was a caching issue.
I've found that for IE (even IE9) that if you nest the self-called function in an anonymous function it works. But it does look like Toddeman's problem was related to the ajax part.
So the code would be:
function locateMe()
{
/* ... */
//IE way (still works in Chrome and FF):
setTimeout(function () { locateMe(); }, 2000);
//original: setTimeout(locateMe, 2000);
}
Use
setTimeout( locateMe, 2000 );
I'm having a lot of JavaScript on my page and I'm using typekit. In order to make my page work correctly (grid and stuff) I'm using the new typekit font events.
It's simply a try and catch statement that checks if fonts get loaded or not. However somehow I'm not getting it. I'm calling the setGrid() function if typekit fonts are loaded, but e.g. iPad or iPhone doesn't support that yet and so my page doesn't get properly shown when I don't call the setGrid() function.
Anyway, I want to call the function in the error statement as well, so if the page is called on the iPhone, the page works without webfonts as well.
try {
Typekit.load({
loading: function() { },
active: function() { setGrid(); },
inactive: function() { }
})
} catch(e) {
alert('error'); //works
setGrid(); //doesn't get called
}
However, the alert works, the setGrid() function doesn't get called.
Any ideas?
edit: the function looks like that:
var setGrid = function () {
$('#header, #footer').fadeIn(500);
return $("#grid").vgrid({
easeing: "easeOutQuint",
time: 800,
delay: 60
});
};
Try making it "real" function, like this:
function setGrid() {
$('#header, #footer').fadeIn(500);
return $("#grid").vgrid({
easeing: "easeOutQuint",
time: 800,
delay: 60
});
};
The function does get called, but it just doesn't work as you expected causing you to think that it isn't getting called. You can see that it is getting called by adding an alert as the first line of setGrid.
jsfiddle link
Can you:
try/catch around setGrid, too
alert after setGrid to confirm it's getting through setGrid