inserting a .on(load) timeout - javascript

I'm attempting to load some images dynamically via .on('load') - via the following script:
.on('load', function() {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
alert('broken image!');
} else {
$("#rateholder").append(img);
}
});
Sometimes, however, the attempt fails for some reason or other. I'd like to put a timeout on it so if the image hasn't loaded within say...10 seconds...it runs a different function.
How would I append a timeout to this?

You can create a function that checks your image exists every 10 seconds.
Then do what you need if it doesn't.
var oneSecond = 1000;
var checkExist = setInterval(function() {
if ($('#the-image').length) {
console.log("Exists!");
clearInterval(checkExist);
}
else{
console.log('Does not Exist');
clearInterval(checkExist);
}
}, oneSecond*10);

Related

setInterval Firing too Often (Javascript)

I have been trying to write code for a simple countdown timer that I am making for a website (take a look here: sbtimescore.github.io). Unfortunately, I've run into a logical error my limited knowledge can't solve (I'm a newbie). When one presses the start/pause repeatedly, the timer starts to speed up. I have posted the code for which is run onclick() below:
function spGameClock() {
if (gameClockRunning == false) {
gameClockRunning = true;
} else {
gameClockRunning = false;
return;
}
function timer() {
if (gameCounter == 0) {
clearInterval(interval);
$("#GameClockText").html(secondsToText(gameCounter));
blinkIt("GameClockBox");
} else if (gameCounter > 0 && gameClockRunning == true) {
$("#GameClockText").html(secondsToText(gameCounter));
gameCounter = gameCounter - 1;
} else if (gameCounter > 0 && gameClockRunning == false) {
clearInterval(interval);
} else {}
}
var interval = setInterval(timer, 1000);
}
I know that the interval is being called too many times, but I'm not sure how to fix it. If anyone has a solution, I would be grateful.
You should define interval as a variable outside of the spGameClock function. A good place would be within the jQuery ready callback. You could then also use that variable itself to determine whether the clock is ticking or not.
Here is an implementation using countdownjs:
$(function () {
var interval = null, // define outside of spGameClock scope
gameCounter = 10; // Some initial value
function spGameClock() {
// Use interval as detection:
if (interval == null) {
interval = setInterval(timer, 1000);
$("#GameClockText").text(secondsToText(gameCounter));
} else {
clearInterval(interval);
interval = null; // Always set to null after clearing
$("#GameClockText").text(secondsToText(gameCounter) + " (paused)");
}
function timer() {
gameCounter--;
$("#GameClockText").text(secondsToText(gameCounter));
// No need to test interval for null here, since it certainly is not.
if (gameCounter <= 0) {
clearInterval(interval);
interval = null;
blinkIt("GameClockBox");
}
}
}
// Attach event handler here instead of using onclick attribute
$("#toggle").click(spGameClock);
// Start clock now
spGameClock();
// Utility functions:
function secondsToText(sec) { // Uses countdown library:
return countdown(new Date().getTime() + 1000*sec).toString() || "Game Over!";
}
function blinkIt(id) {
(function loop(times) {
if (times) $('#' + id).fadeToggle(400, loop.bind(null, times-1));
})(6);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/countdown/2.6.0/countdown.min.js"></script>
<button type="button" id="toggle">Pause/Continue</button>
<div id="GameClockBox">
<div id="GameClockText"></div>
</div>

Adobe Edge HTML5 Local Connection

I`m trying to create two banners with adobeEdge and import them with iframes within 3rd file. So the structure would be something like this:
banner1.html
banner2.html
index.html (where banner1 and banner2 will be embed via iframe).
Those two banners will be animated, however file size, loading time of each may vary so they will not be loaded in the same time.
The problem is that I need them both to start playing in exact same time (in flash that is called local connection), so the idea is to check when both iframes are loaded and if each of them send DONE message to the other one I will play them.
I wrote a code which actually work, but still one banner always has a delay. Here is my code:
Banner 1
<script type="text/javascript">
var fr = window.parent.frames["frame2"];
var frwin = fr.contentWindow;
var otherLoaded = false;
var selfLoaded = false;
var process = setInterval(function(){load();},10);
window.addEventListener("message", receiveMessage, false);
function setLoaded(){
selfLoaded = true;
frwin.postMessage("Done", "DOMAIN");
}
function load(){
if(otherLoaded === true && selfLoaded === true){
clearInterval(process);
AdobeEdge.bootstrapCallback(function(compId) {
AdobeEdge.getComposition(compId).getStage().play();
});
}else if(selfLoaded === true && otherLoaded !== true){
frwin.postMessage("resend", "http://izorgor.com");
}
}
function receiveMessage(event) {
if (event.origin !== "DOMAIN")
return;
if(event.data === 'Done'){
otherLoaded = true;
console.log("Done");
}
if(event.data === 'resend'){
fr = window.parent.frames["frame2"];
frwin = fr.contentWindow;
frwin.postMessage("Done", "DOMAIN");
console.log("resend");
}
}
</script>
Banner 2
<script type="text/javascript">
var fr = window.parent.frames["frame1"];
var frwin = fr.contentWindow;
var otherLoaded = false;
var selfLoaded = false;
var process = setInterval(function(){load();},10);
window.addEventListener("message", receiveMessage, false);
function setLoaded(){
selfLoaded = true;
frwin.postMessage("Done", "DOMAIN");
}
function load(){
if(otherLoaded === true && selfLoaded === true){
clearInterval(process);
AdobeEdge.bootstrapCallback(function(compId) {
AdobeEdge.getComposition(compId).getStage().play();
});
}else if(selfLoaded === true && otherLoaded !== true){
frwin.postMessage("resend", "http://izorgor.com");
}
}
function receiveMessage(event) {
if (event.origin !== "DOMAIN")
return;
if(event.data === 'Done'){
otherLoaded = true;
console.log("Done");
}
if(event.data === 'resend'){
fr = window.parent.frames["frame1"];
frwin = fr.contentWindow;
frwin.postMessage("Done", "DOMAIN");
console.log("resend");
}
}
</script>
index.html
<iframe width="900" height="200" id="frame1" src="banner1.html" frameborder="0" scrolling="no"></iframe>
Thanks
I think you should contact your AdServer and ask if they are serving the Ad in just one TAG or in two TAGs
You can use libraries as https://github.com/jeremyharris/LocalConnection.js/tree/master
(similar to Flash Local Connection)
You can simply communicate between all your iframes in a window with a JavaScript library that I developed.
Get Documentation or Fork on GitHub. It uses nativ DOM to connect iframes with each other.
Sample usage :
include first LocalConnection script to all your banner. In this sample code we assume there are 2 banners need to communicate with each other. But it works also any number of banners.
in first banner :
<script>
LC.key = 'uniqueConnectionString';
LC.name = 'right'; // desc: my name is right and
LC.frames = 'left'; // I want to connect to the banner called left
LC.onConnect = function () {
console.log('Do this as soon as connection established!');
/*
From this point window of left and top will be available as
LC.left and LC.top
for example :
*/
LC.left.document.getElementsByTagName('body')[0].style.backgroundColor = 'pink';
};
</script>
On the second banner put the same code but change name and frames values like this :
<script>
LC.key = 'uniqueConnectionString';
LC.name = 'left'; // desc: my name is left and
LC.frames = 'right'; // I want to connect to the banner called right
LC.onConnect = function () {
console.log('Do this as soon as connection established!');
/*
From this point window of left and top will be available as
LC.left and LC.top
for example :
*/
LC.left.document.getElementsByTagName('body')[0].style.backgroundColor = 'pink';
};
LC.connect();
</script>

How do I check if a jQuery object exists in the DOM?

I want to check if a jQuery object exists in the DOM (with Internet Explorer). I tried this code:
observeEditor = function(editor) {
function update_position() {
console.log("update_position");
var $editor = jQuery(editor);
if (jQuery(document).find($editor).length > 0) {
// call our function
setTimeout(update_position, 250);
}
}
setTimeout(update_position, 250);
};
But the problem is that even after I close the editor (it doesn't exist in the DOM), I still get this console.log every 250 ms. How do I check if the element exists in the DOM? I receive the variable editor as a parameter.
Please notice, the editor may also be inside an <iframe>.
I found a solution, it's not ideal but it works. I gave every editor a unique data attribute:
if (($editor.length === 1) && (typeof($editor.attr('data-editor-id')) === 'undefined')) {
$editor.attr('data-editor-id', Math.floor((Math.random() * 900000000000000) + 100000000000000));
}
And then I changed the function:
observeEditor = function(editor) {
var $editor = jQuery(editor);
var editor_id = undefined;
if (($editor.length === 1) && (!(typeof($editor.attr('data-editor-id')) === 'undefined'))) {
editor_id = $editor.attr('data-editor-id');
}
function update_position() {
console.log("update_position");
if (jQuery(document).find('[data-editor-id="' + editor_id + '"]').length > 0) {
// call our function
setTimeout(update_position, 100);
}
}
setTimeout(update_position, 100);
};
By the way, I changed the timout to 100 ms because it's too slow with 250.

jquery handle if multiple time click

i am trying to do own slider animation of my webpage on my own js code using jquery library,I have one function, in that function i wrote move dom element using animation method with set parameter which element want animate, its working good when calling automatic repeat using setInterval, but if click next or prev button continuously on multiple time, it calling slide function continually how much time i click, so continuously calling method, collapse the css and dom elements that is making my slider ugly :(, kindly help me how can i prevent that issue, I am trying search and get that solution , but i can't get solution, Kindly help needful
click event :
$(".health-plan-slider .next").stop().click( function(){
var ele_n = $(".health-plan-slider .next").attr("data-next");
slideEffectNext( ele_n );
});
function :
function slideEffectNext(dataVal)
{
dataVal = parseInt(dataVal);
var dataValPrev = parseInt(dataVal) - 1;
if( dataVal == ele_len-1 )
{
$(".health-plan-slider .next").attr("data-next",0);
}
else
{
$(".health-plan-slider .next").attr("data-next", dataVal+1);
}
if( dataVal == 0 )
{
$(".health-plan-slider .prev").attr("data-prev", ele_len-1);
}
else
{
$(".health-plan-slider .prev").attr("data-prev", dataVal-1);
}
$(".slider-wrap .slide-elements").removeAttr("data-cur");
$(".slider-wrap .slide-elements").eq(dataVal).css("left", "920px");
$(".slider-wrap .slide-elements").eq(dataValPrev).animate({ left:-920+"px"}, 1000, function() { $(".slider-wrap .slide-elements").eq(dataValPrev).css("left",920+"px");});
$(".slider-wrap .slide-elements").eq(dataVal).animate({ left:0+"px"}, 1000).attr("data-cur", 1);
}
Advance thanks
Use
.stop()
to stop animation each time you click next or prev
$('#next').stop().click(function() {
// your animation ..
})
same for $('#prev')
try this logic
$(".health-plan-slider .next").click( function(){
if(typeof sliding != "undefined" && sliding){
var ele_n = $(".health-plan-slider .next").attr("data-next");
slideEffectNext( ele_n );
}
});
function slideEffectNext(dataVal){
sliding = true;
dataVal = parseInt(dataVal);
var dataValPrev = parseInt(dataVal) - 1;
if( dataVal == ele_len-1 )
{
$(".health-plan-slider .next").attr("data-next",0);
}
else
{
$(".health-plan-slider .next").attr("data-next", dataVal+1);
}
if( dataVal == 0 )
{
$(".health-plan-slider .prev").attr("data-prev", ele_len-1);
}
else
{
$(".health-plan-slider .prev").attr("data-prev", dataVal-1);
}
$(".slider-wrap .slide-elements").removeAttr("data-cur");
$(".slider-wrap .slide-elements").eq(dataVal).css("left", "920px");
$(".slider-wrap .slide-elements").eq(dataValPrev).animate({ left:-920+"px"}, 1000, function() { $(".slider-wrap .slide-elements").eq(dataValPrev).css("left",920+"px");});
$(".slider-wrap .slide-elements").eq(dataVal).animate({ left:0+"px"}, 1000,function(){sliding = false;}).attr("data-cur", 1);
}

xhr.status and xhr.readyState is 0

I'm working with HTML5 multiple file uploader. For some purpose I'm queuing the requests into a JavaScript array and I'm trying with two approaches here, one is, sending all the requests by a loop using a for loop and the next approach is like starting the next request after the previous request got finished. Here is the code,
function processUploads(i)
{
if(typeof(i)=="undefined")
return;
if(i==0)
{
for(i=0;i<4;i++)
{
xhrQ[i].open("POST",FUurl,true);
xhrQ[i].send(fdQ[i]);
xhrQ[i].onreadystatechange = function() {
if (xhrQ[i].readyState == 4 && xhrQ[i].status == 200) {
uploadComplete(xhrQ[i],i);
}
}
}
}
else
{
xhrQ[i].open("POST",FUurl,true);
xhrQ[i].send(fdQ[i]);
xhrQ[i].onreadystatechange = function() {
if (xhrQ[i].readyState == 4 && xhrQ[i].status == 200) {
uploadComplete(xhrQ[i],i);
}
}
}
}
function uploadComplete(xhr,i)
{
//processUploads(i+1);
var responseJSON = eval('(' + xhr.responseText + ')');
var upldrID = responseJSON.data.queueId;
var fileProgElem = $("#file_content").find("div[file-count="+upldrID+"]");
fileProgElem.attr("upload","finished");
fileProgElem.find("input[id=asset_id]").val(responseJSON.data.asset_id);
if(typeof(responseJSON)=="undefined") {
return;
}
$("#bar"+upldrID).css("width: 100%");
$("#progress_text"+upldrID).addClass("hide");
$("#progress_bar"+upldrID).html("Upload Complete!");
var pagename = $("#pagename").attr('value');
var cover_art = "<img src='"+responseJSON.data.thumb_location+"' alt='"+$.trim($("#file_name"+upldrID).html())+"' />";
$("#cover_art"+upldrID).html(cover_art);
//Hide the cross icon and enable the save
var action_divs = '<div id="done'+upldrID+'" class="hide enable">'
+'<a id="delete_file_'+upldrID+'" onclick="saveWorkspaceFileDetails(\''+responseJSON.data.project_id+'\',\''+responseJSON.data.asset_id+'\',\''+upldrID+'\',\''+responseJSON.data.file_name+'\',\''+responseJSON.data.size+'\',\'delete\',\''+pagename+'\')">'
+'<i class="tl-icon-20-close-gray"></i>'
+'</a>'
+'</div>';
$("#cancel_upload"+upldrID).append(action_divs);
$("#progress_cancel"+upldrID).addClass("hide").removeClass("show");
$("#done"+upldrID).addClass("show").removeClass("hide");
//To show the post and cancel button
$("#submitFileUpload").removeClass("hide").addClass("show");
//Updating the title with the default value of file_name
var file_title = $.trim($("#file[file-count='"+upldrID+"']").find("#file_title").val());
if (file_title == "" && file_title != undefined){
$("#file[file-count='"+upldrID+"']").find("#file_title").val(responseJSON.data.file_name);
}
//For other category we need to enable the dropdown
if(responseJSON.data.category_id=='999')
{
$("#select_category"+upldrID).removeClass("hide").addClass("show");
}
//totSelFiles is a number of selected files that i sets as a global variable
if(i<(totSelFiles-1))
{
processUploads(i+1);
}
else
return;
}
But the problem is i'm getting the readyState and status as 0 in the if loop. But the file is getting uploaded to the server and the else condition is also working well if i only enable that block. So what could be the problem. I'm greatly confused. Any help would be greatly appreciate.
The problem is related to the closure you create with the anonymous function you use for onreadystatechange. It will have access to the value of i, but not from the time of creation of the closure but rather from the time of its execution. At that point of time i is always 4 and xhrQ[i] will not refer to the correct object. Use this instead
xhrQ[i].onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
}
}
The problem is that you want to continue with the index i inside the uploadComplete() function. For this you might need to create another inner closure with an immediately executing function that will create a local copy of the current index.
xhrQ[i].onreadystatechange = (function(_innerI) {
var that = this;
return function() {
if(that.readyState == 4 && that.status == 200) {
uploadComplete(that, _innerI);
}
}
})(i);

Categories