I have got a problem with my jQuery code which supposed to detect connectivity to the internet.
function checkConnection() {
var connected = true;
var img = document.createElement('img');
img.src = "https://p5-zbjpil5uzqzqg-b5icu4xm7kglqch5-458861-i2-v6exp3-ds.metric.gstatic.com/v6exp3/6.gif";
img.onerror = function () {
connected = false;
};
return connected;
}
setInterval(function () {
var isConnected = checkConnection(); // checkConnection() comes from above code
if (isConnected) {
alert('internet');
} else {
alert('no internet');
}
}, 3000);
It doesn't matter wheater I am online or offline there is the same alert window INTERNET comes up. Can you please help to fix the code? The fiddle is available below, feel free to amend it.
http://jsfiddle.net/yV28D/2/
Many thanks.
When dealing with events, you typically want to use callbacks.
http://jsfiddle.net/yV28D/3/
function checkConnection(callback) {
var img = document.createElement('img');
img.onerror = function () {
callback(false);
};
img.onload = function() {
callback(true);
};
img.src = "https://p5-zbjpil5uzqzqg-b5icu4xm7kglqch5-458861-i2-v6exp3-ds.metric.gstatic.com/v6exp3/6.gif";
}
setInterval(function () {
checkConnection(function(isConnected){
if (isConnected) {
console.log('internet');
} else {
console.log('no internet');
}
}); // checkConnection() comes from above code
}, 3000);
Otherwise, you will always get true because the return is happening before the error callback has a chance to be executed.
Also, when dealing with onload and onerror events, you always want to bind the events before you set the src, otherwise it's possible for the event to happen before you bind to it.
Related
I've no idea if this is the right way to do what I'm trying to do (I have 0 experience with jQuery/Javascript):
window.onload = function () {
var Btn = document.getElementById('fmm-payment-btn');
Btn.onclick = function () {
gtag_report_conversion();
}
}
The gtag_report_conversion() looks like this:
function gtag_report_conversion(url) {
var callback = function () {
if (typeof(url) != 'undefined') {
window.location = url;
}
};
gtag('event', 'conversion', {
'send_to': 'AW-URLHERE',
'transaction_id': '',
'event_callback': callback
});
return false;
}
Basically, I'd like to make sure that the function gtag_report_conversion() is executed when users click on fmm-payment-btn (to track conversions in Google Ads).
I tried this in a slightly different way using document.getElementById("fmm-payment-btn").onclick = function() but I kept getting an error, Uncaught TypeError: Cannot set property 'onclick' of null. I understand the method above should work better, but having no experience I cannot tell.
Would appreciate any feedback. :)
window.onload doesn't mean that the DOM is loaded.
If you want to be sure that the button is rendered you should use
window.addEventListener('DOMContentLoaded', (event) => {
console.log('DOM fully loaded and parsed');
document.getElementById("fmm-payment-btn").onclick = function(){}
// Or
document.getElementById("fmm-payment-btn").addEventlistener('click', function(){})
// Or even cleaner
document.getElementById("fmm-payment-btn").addEventlistener('click', gtag_report_conversion)
});
I have an external JS file that adds a window.onload function to the page.
The basic premise is that it loads up a popup window on your website whenever the user clicks on certain link class. It's written in PHP / JS so assume that the function works by itself.
Inside this JS file has the following code.
window.onload = function() {
var anchors = document.getElementsByClassName("vyper-triggers");
for (var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
anchor.onclick = function() {
if (isMobile.any()) {
window.open("$url");
} else {
document.getElementById("clickonthis").click();
}
}
}
}
Now my problem is when my user wants to add 2 different popup windows, the window.onload function doesn't stack. Also because this is an embedded javascript that my user adds himself, there is no way for me to put both functions inside one big window.onload function.
My user might put one JS file in one area of their site, and another JS file in another area, if that makes sense.
So how do I make it so that the window.onload function will stack no matter the placing of these external JS files on the page and considering that each function must be kept separate?
Rather than setting window.onload, you should use addEventListener. Listeners added this way will stack automatically.
window.addEventListener('load', function() {
console.log('First listener');
});
window.addEventListener('load', function() {
console.log('Second listener');
});
window.addEventListener('load', function() {
console.log('Third listener');
});
If you have to support versions of IE before IE9, there's a polyfill which will make this work correctly.
Probably you have multiple files and u want to check something onload.
Let's implement a basic function to add other functions and run all of them when the event onload is triggered.
So, first we check if windows.onload has a function object if not add our function. If is contains a function object merge it with our function like this:
function addLoadEvent(callback) {
const previous = window.onload
if (typeof previous === 'function') {
window.onload = (e) => {
if (previous) previous(e)
callback(e)
}
}
...
}
This is an example how to use it:
function addLoadEvent(callback) {
const previous = window.onload
if (typeof previous === 'function') {
window.onload = (e) => {
if (previous) previous(e)
callback(e)
}
} else {
window.onload = callback
}
}
function func1() {
console.log('This is the first.')
}
function func2() {
console.log('This is the second.')
}
addLoadEvent(func1);
addLoadEvent(func2);
addLoadEvent(() => {
console.log('This is the third.')
document.body.style.backgroundColor = '#EFDF95'
})
I'm using this code, which has stemmed from here and here.
$('#my_button').on('click', function (e) {
var iframe = document.createElement('iframe');
iframe.id = "my_iframe";
iframe.onload = function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.getElementsByTagName('body')[0].innerHTML = "<p>test123</p>";
iframe.contentWindow.focus();
iframe.contentWindow.print();
$("#my_iframe", top.document).remove();
};
document.getElementsByTagName('body')[0].appendChild(iframe);
});
Without the remove line, it prints fine. However, the remove line removes the iframe before it has a chance to execute the print(). How can I set up some kind of callback so that it prints and only then removes the iframe?
Thanks.
I found this solution when I was searching for print event detection:
http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/
Here I add the JS code as requested by Stano, but it is important to also read the whole linked post as there are limitations to this approach. In general the post is about the onafterprint event that only works in IE and a solution to make that event work in other browsers.
(function() {
var beforePrint = function() {
console.log('Functionality to run before printing.');
};
var afterPrint = function() {
console.log('Functionality to run after printing');
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
}());
create a function like this:
function printIframe(iframe,callback) {
iframe.contentWindow.print();
if (callback && typeof(callback) === "function") {
// execute the callback, passing parameters as necessary
callback();
}
}
and call it instead of the other two functions like this.
printIframe(iframe,function(){ $("#my_iframe", top.document).remove();})
if you like you can also put in a delay using the setTimeout.
setTimeout(function() {alert('hello');},1250);
Jquery provides a very convenient way to delay executing code until the DOM is fully loaded:
$(function() {
dom_is_loaded();
});
The Facebook Javascript SDK, when loaded asynchronously, provides a similar mechanism:
window.fbAsyncInit = function() {
fb_is_loaded();
}
What's the most elegant way to delay code from running until the DOM and Facebook's SDK have both fully initialized?
Is there a reason why just doing
window.fbAsyncInit = function() {
$(function() {
both_loaded();
});
}
doesn't work?
Why not:
var jq_ready = false, fb_ready = false;
function bothReady(){
...
}
$(function() {
dom_is_loaded();
jq_ready = true;
if(fb_ready){
bothReady();
}
});
window.fbAsyncInit = function() {
fb_is_loaded();
fb_ready = true;
if(jq_ready){
bothReady();
}
}
I think this is cleaner than setting an interval and will handle either event happening first.
Probably set a flag in your fbAsyncInit function and check it in the jQuery load:
$(handleLoad);
function handleLoad() {
if (!facebookLoaded) {
setTimeout(handleLoad, 10); // Or 100 or whatever
}
else {
// You're good to go
bothLoaded();
}
}
I expect there's already some global you can check for whether Facebook is loaded (I haven't used the Facebook API). If not, you can use your own flag (ideally not a global):
(function() {
var fbLoaded = false;
window.fbAsyncInit = function() {
fbLoaded = true;
};
jQuery(handleLoad);
function handleLoad() {
if (!facebookLoaded) {
setTimeout(handleLoad, 10); // Or 100 or whatever
}
else {
// You're good to go
bothLoaded();
}
}
})();
You might want to check out this explanation
http://pivotallabs.com/users/jdean/blog/articles/1400-working-with-asynchronously-loaded-javascript
I'm trying to do something similar to this...
if (window.onblur) {
setTimeout(function () {
DTitChange(name)
}, 1000)
} else {
document.title = dtit
}
The window.onblur doesn't seem to be working though, is there something I can replace that with?
What do you mean by doesn't seem to be working? Here's what you are currently saying:
If there's an onblur event handler:
execute DTitChange once ever second.
Else
document.title = dtit
Which is probably not what you want. Try
window.onblur = function () {
setTimeout(function () { DTitChange(name) }, 1000);
};
also make sure that you set an onfocus handler as to clear the timeout if you want it to stop happening when the user returns. :)
You should assign a function to window.onblur, in your question you're only testing if the property onblur exists. But window.onblur doesn't always work correctly in every browser. The article Detecting focus of a browser window shows how to set this up. In your case it would be something like:
function DTitBlur() {
/* change title of page to ‘name’ */
setTimeout(function () {
DTitChange(name)
}, 1000);
}
function DTitFocus() {
/* set title of page to previous value */
}
if (/*#cc_on!#*/false) { // check for Internet Explorer
document.onfocusin = DTitFocus;
document.onfocusout = DTitBlur;
} else {
window.onfocus = DTitFocus;
window.onblur = DTitBlur;
}