this questions is related to an html file calling out different pages in different iframe tags. Is there a way, using JavaScript probably, to check if there was a connection issue to the page? If so, to try reloading this frame until the connection is established.
To be a bit clearer, if you have a look at the following link (http://tvgl.barzalou.com) (even if the content is in French, you will notice how different parts of the page load, and more often than not, loads correctly). But once in a while, during the weekend, a slight connection issue to the net arrives and for some reason, the frame gives out this ridiculous grey / light grey icon saying that there was a connection issue. Of course, when the page is manually reloaded, the frame comes back to life.
Please check the updated code that will check and reload the iframe after the max attempts have been reached...
<script language="javascript">
var attempts = 0;
var maxattempt = 10;
var intid=0;
$(function()
{
intid = setInterval(function()
{
$("iframe").each(function()
{
if(iframeHasContent($(this)))
{
//iframe has been successfully loaded
}
if(attempts < maxattempt)
{
attempts++;
}
else
{
clearInterval(intid);
checkAndReloadIFrames();
}
})
},1000);
})
function iframeHasContent($iframe)
{
if($iframe.contents().find("html body").children() > 0)
{
return true;
}
return false;
}
function checkAndReloadIFrames()
{
$("iframe").each(function()
{
//If the iframe is not loaded, reload the iframe by reapplying the current src attribute
if(!iframeHasContent($(this)))
{
//reload iframes if not loaded
var $iframe = $(this);
var src = $iframe.attr("src");
//code to prevent cache request and reload url
src += "?_" + new Date().getTime();
$iframe.attr("src",src);
}
});
}
</script>
You can schedule a code which will check whether the iframes are loaded properly or not
Consider a sample
<script language="javascript">
var attempts = 0;
var maxattempt = 10;
var intid=0;
$(function()
{
intid = setInterval(function()
{
$("iframe").each(function()
{
if(iframeHasContent($(this)))
{
//iframe has been successfully loaded
}
if(attempts < maxattempt)
{
attempts++;
}
else
{
clearInterval(intid);
}
})
},1000);
})
function iframeHasContent($iframe)
{
if($iframe.contents().find("html body").children() > 0)
{
return true;
}
return false;
}
</script>
This simple code snippet will check whether iframes in the document have been loaded properly or not. It will try this for 10 attempts then it will abort the checking.
When the checking is aborted, you can call iframeHasContent() for each iframe to shortlist the ones that have not been loaded and reload them if required.
Related
I am trying to refresh the page only one time when a particular URL is hit.
The reason for this is to refresh the data on the view. My URL is
http://localhost:8072/web?#min=1&limit=80&view_type=list&model=pos.order&action=405
And solutions I have tried are
window.onload = function() {
//considering there aren't any hashes in the urls already
if(!window.location.hash) {
//setting window location
window.location = window.location + '#loaded';
//using reload() method to reload web page
window.location.reload();
}
}
(function()
{
if( window.localStorage )
{
//check if reloaded once already
if( !localStorage.getItem('firstLoad') )
{
//if not reloaded once, then set firstload to true
localStorage = true;
//reload the webpage using reload() method
window.location.reload();
}
else
localStorage.removeItem('firstLoad');
}
})();
$(document).ready(function(){
//Check if the current URL contains '# or hash'
if(document.URL.indexOf("#")==-1){
// Set the URL to whatever it was plus "#loaded".
url = document.URL+"#loaded";
location = "#loaded";
//Reload the page using reload() method
location.reload(true);
}
});
None of them worked for me. What is wrong or which direction should I choose?
Your first solution works fine, it just needed a return statement to prevent execution the rest of the code, however if your original url contains a hash, you can do the check like this:
window.onload = function() {
document.getElementById("test").textContent = window.location;
console.log(window.location.hash);
//check for our specific hash argument
if (!window.location.hash.match(/[#&]loaded(&|$)/)) {
alert("the page is about to refresh");
//setting window location
window.location = window.location + (window.location.hash ? "&" : "#") + 'loaded';
//using reload() method to reload web page
window.location.reload();
return;
}
alert("page refreshed");
}
<div id="test"></div>
We need a solution to the following issue.
We currently refresh a screen every 30 seconds, what we need to do prior to the actual refresh is check if the website is still up and if there is a network present to access the page.
If the page is down then we delay the refresh by 6 seconds this is repeated 5 times.
If the fifth attempt is showing that the website is still down then an error message is displayed.
This is working fine but we need to check if the website is still available (ping the website prior to refreshing) and also we need a solution if the browser starts to refresh but loses the connection or the server goes down once the refresh has started
This is the current code
window.onload = function () {
var refresh_rate = 30; //<-- Second until refresh
var connection_attempts=5; ////// Connection attempts
var failed_seconds=6;
var inactivity_counter = 0;
var connection_failed= 0;
function reset1() {
inactivity_counter = 0;
console.log("Reset1");
}
function reset2() {
inactivity_counter = 0;
console.log("Reset2");
}
function reset3() {
inactivity_counter = 0;
connection_failed = 0;
console.log("Reset3");
}
function reset_network() {
inactivity_counter = (refresh_rate - failed_seconds);
console.log("ResetNetwork");
}
setInterval(function () {
inactivity_counter++;
refreshCheck();
}, 1000);
function can_i_refresh() {
if (inactivity_counter >= refresh_rate) {
return true;
}
return false;
}
function refreshCheck() {
if (can_i_refresh()) {
if(navigator.onLine) {
connection_failed='0';
window.location.href='alreadybooked.php?location=5';
inactivity_counter = 0;
}
else {
connection_failed++;
console.log(connection_failed);
if(connection_failed==connection_attempts) {
alert("Error 1001: This check-in device is currently experiencing issues. Please check-in on another device. If you still experience issues, please press the 'OK' button and proceed to reception");
return false;
}
reset_network();
}
}
else {
console.log(inactivity_counter);
}
}
window.addEventListener("click", reset1);
window.addEventListener("mousemove", reset2);
};
This should do what you need.
The function setupPageReload() creates a timeout so that the page reload will start after the specified delay. The actual reload is done into a temporary element, so the check for availability and the reload are the same thing. If the reload doesn't happen (for any reason) then the fail counter is incremented and will execute the fatalError() function if there have been enough retries. If it works then it simply replaces the contents of the current page with the contents that were just downloaded. Unless there was a "fatal error" then the function is simply executed again to start the process all over.
var refreshRate = 30;
var connectionAttempts = 5;
var connectionFailed = 0;
function setupPageReload() {
setTimeout(function() {
$("<div/>").load(location.href + " body", function(response, status) {
if (status == "success") {
connectionFailed = 0;
$("body").html(response);
setupPageReload();
}
else {
if (++connectionFailed === connectionAttempts) {
fatalError();
}
else {
setupPageReload();
}
}
});
}, refreshRate * 1000);
}
function fatalError() {
alert("Error 1001: This check-in device is currently experiencing issues. " +
"Please check-in on another device. If you still experience issues, " +
"please press the 'OK' button and proceed to reception");
}
window.onload = setupPageReload;
Incidentally, this method requires jQuery as that performs the ajax download and gets the content of the <body/> tag much, much easier than if you were to do that in vanilla js. If you don't already use that in the page in question then you'll need to add a script include.
There is a angularjs application, I am working out of it. in my web page, I am getting application loaded in the iframe - I just want to know whether the ifame loaded or not. for that, I use:
//but i don't like this.
var myTimeout = function () {
setTimeout(function(){
if($('.ssueContentIframe').length > 0 ) {
penetrate();
return;
}
myTimeout();
}, 10000);
};
myTimeout();
in the iframe there is number of content keep loading and changing. But one of the event I would require to add in the element with class name of .ui-grid-icon-ok - how can I hear from document that the element existence - any one help me?
If there's no constraints CORS or XSS, you should be able to do something like the following.
var what = document.getElementById('what');
function checkIframeLoaded() {
try {
// Get a handle to the iframe element
var iframe = document.getElementById('iframe');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
what.appendChild(document.createTextNode("Checking...\n"));
// Check if loading is complete
if (iframeDoc.readyState == 'complete') {
afterLoading();
return;
}
} catch (err) {
alert(err);
}
// If we are here, it is not loaded. Set things up so we check the status again in 100 milliseconds
window.setTimeout(checkIframeLoaded, 100);
}
function afterLoading() {
what.appendChild(document.createTextNode("It loaded!\n"));
}
checkIframeLoaded();
iframe {
width: 100px;
height: 25px;
}
<iframe id="iframe" src="data:text/plain,"></iframe>
<pre id="what">Not loaded.</pre>
If there are any constraints (e.g. sandboxing, CORS, XSS, etc.), you'll get an alert dialog every 10th of a second with the error, and I hope you have the ability to click the checkbox to ignore them. :)
Note: This is a modified version of this other stack overflow answer, expanded to demonstrate errors.
Rewriting the question -
I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com
I made a program as follows -
var stayonthis = true;
var a;
function load() {
window.onbeforeunload = function(e) {
if(stayonthis){
a = setTimeout('window.location.href="http://google.com";',100);
stayonthis = false;
return "Do you really want to leave now?";
}
else {
clearTimeout(a);
}
};
window.onunload = function(e) {
clearTimeout(a);
};
}
window.onload = load;
but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(
Help Me !! Thanks in Advance
here is the fiddle code
here how you can test because onbeforeunload does not work on iframe well
This solution works in all cases, using back browser button, setting new url in address bar or use links.
What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler.
In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)
http://jsfiddle.net/W3vUB/4/show
http://jsfiddle.net/W3vUB/4/
EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!)
BTW, using bing.com due to google not allowing no more content being displayed inside iframe.
http://codepen.io/anon/pen/dYKKbZ
var a, b = false,
c = "http://bing.com";
function triggerEvent(el, type) {
if ((el[type] || false) && typeof el[type] == 'function') {
el[type](el);
}
}
$(function () {
$('a:not([href^=#])').on('click', function (e) {
e.preventDefault();
if (confirm("Do you really want to leave now?")) c = this.href;
triggerEvent(window, 'onbeforeunload');
});
});
window.onbeforeunload = function (e) {
if (b) return;
a = setTimeout(function () {
b = true;
window.location.href = c;
c = "http://bing.com";
console.log(c);
}, 500);
return "Do you really want to leave now?";
}
window.onunload = function () {
clearTimeout(a);
}
It's better to Check it local.
Check out the comments and try this: LIVE DEMO
var linkClick=false;
document.onclick = function(e)
{
linkClick = true;
var elemntTagName = e.target.tagName;
if(elemntTagName=='A')
{
e.target.getAttribute("href");
if(!confirm('Are your sure you want to leave?'))
{
window.location.href = "http://google.com";
console.log("http://google.com");
}
else
{
window.location.href = e.target.getAttribute("href");
console.log(e.target.getAttribute("href"));
}
return false;
}
}
function OnBeforeUnLoad ()
{
return "Are you sure?";
linkClick=false;
window.location.href = "http://google.com";
console.log("http://google.com");
}
And change your html code to this:
<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
try it
</body>
After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.
jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN
var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;
var handler = function(e) {
timeout = setTimeout(function () {
console.log('location.assign');
location.assign(offerUrl);
/*
* This value makes or breaks it.
* You need enough time so the browser can make the connection to
* the clicked links href else it will still redirect to the offer url.
*/
}, 1400);
// important!
window.onbeforeunload = F;
console.info('handler');
return 'Do you wan\'t to leave now?';
};
window.onbeforeunload = handler;
Try the following, (adds a global function that checks the state all the time though).
var redirected=false;
$(window).bind('beforeunload', function(e){
if(redirected)
return;
var orgLoc=window.location.href;
$(window).bind('focus.unloadev',function(e){
if(redirected==true)
return;
$(window).unbind('focus.unloadev');
window.setTimeout(function(){
if(window.location.href!=orgLoc)
return;
console.log('redirect...');
window.location.replace('http://google.com');
},6000);
redirected=true;
});
console.log('before2');
return "okdoky2";
});
$(window).unload(function(e){console.log('unloading...');redirected=true;});
<script>
function endSession() {
// Browser or Broswer tab is closed
// Write code here
alert('Browser or Broswer tab closed');
}
</script>
<body onpagehide="endSession();">
I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...
Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)
Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.
I want to make things happen with DOM elements as soon as they are loaded (found nothing with search on this site or Google, but it is hard to explain this with few words). For example, when a big page is loading I want to hide/add onlick events/etc. to elements as soon as they appear on user's screen not on $(document).ready(). I wrote a simple class (just for training, closures are new for me so there may be lots of errors) that does what I want but I want to use something better for commercial useb(on the site I'm helping to develop). Here is my source code:
function MY_loader() {
function container() {
this.add_event = function(new_event,obj_selector,settings) {
if(typeof(settings)!='object') {
settings={};
}
if(typeof(settings.event_id)!='string') {
settings.event_id=gen_new_event_id();
}
settings=$.extend({},default_settings,settings);
settings.obj_selector=obj_selector;
settings.event=new_event;
events[settings.event_id]=settings;
}
this.execute_events = function(if_force) {
if(typeof(if_force)=='undefined') {
if_force=false;
}
if(html_is_loaded&&!if_force) {
return;
}
var temp_obj;
for(var event_name in events) {
temp_obj=$(events[event_name].obj_selector);
if(temp_obj.length || (html_is_loaded && events[event_name].if_force)) {
temp_obj.each(function() {
if(events[event_name].expect_multiple) {
if($(this).data('my_loader_'+events[event_name].event_id+'_executed')) {
return;
}
}
if(events[event_name].event_type!='func') {
$(this).bind(events[event_name].event_type+'.'+events[event_name].event_id,events[event_name].event);
}
else {
events[event_name].event($(this));
}
if(events[event_name].expect_multiple) {
alert('here');
$(this).data('my_loader_'+events[event_name].event_id+'_executed',1);
}
});
//alert(events[event_name].obj_selector+' '+events[event_name].event_type);
if(!events[event_name].expect_multiple) {
delete events[event_name];
}
}
}
if(!html_is_loaded) {
var cur_time=new Date().getTime();
setTimeout('MY_loader().execute_events();',Math.max(Math.min(tick_time-(cur_time-last_tick_time),tick_time),0,min_tick_diff));
last_tick_time=cur_time;
}
}
this.html_is_loaded_set=function(if_html_is_loaded) {
html_is_loaded=if_html_is_loaded?true:false;
};
this.html_is_loaded_get=function() {
return html_is_loaded?true:false;
};
return this;
}
function instance(if_strat) {
if(typeof(class_is_loaded)=='undefined'||!class_is_loaded) {
load_class();
}
return container(if_strat);
}
var load_class=function() {
this.class_is_loaded=true;
this.events = {};
this.allowed_event_id_chars='abcdefghijklmnopqrstuvwxyz0123456789';
this.default_settings={
'event_type':'click',
'if_force':false,
'expect_multiple':false
};
this.tick_time=500;
this.min_tick_diff=100;
this.last_tick_time=0;
this.html_is_loaded=false;
MY_loader().execute_events();
$(document).ready(function(){
MY_loader().html_is_loaded_set(true);
MY_loader().execute_events(true);
});
}
var gen_new_event_id=function() {
for(var new_id=gen_random_id();typeof(events[new_id])!='undefined';new_id=gen_random_id());
return new_id;
}
var gen_random_id=function() {
var allowed_event_id_chars_size=allowed_event_id_chars.length;
var new_id='';
for(var i=0;i<10;i++) {
new_id+=allowed_event_id_chars[get_random_int(0,allowed_event_id_chars_size-1)];
}
return new_id;
}
function get_random_int(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return new instance();
}
//Add click event to #some_selector (once and dont check after it)
MY_loader().add_event(function() {
alert($(this).val());
}, '#some_selector');
//Hide elements as soon as they are loaded.
//We expect multiple elements with this selector, so it will
//check for this elements untill document is loaded, but this function
//will be applied only one time for each element.
MY_loader().add_event(function(obj) {
obj.hide();
alert('This should happen before DOM is completely loaded!');
}, '.some_other_selector',{'event_type':'func','expect_multiple':true});
//This alert should be outputted the last
$(document).ready(function(){
alert('Document is fully loaded!');
});
UPD: To make this question a little bit more interesting as it seems too specific I must add: most of the browsers start page rendering before it is completely loaded (this seems to be not well-known for some reason), here are a few links:
http://en.wikipedia.org/wiki/Incremental_rendering
When do browsers start to render partially transmitted HTML?
http://www.vbulletin.org/forum/showthread.php?t=161099
So, my problem should be more widely known as this incremental page loading adds lots of problems for developer: user can click on non-working buttons before page is loaded, some things that are hidden by JavaScript on load may show and they can be ugly, etc. (this are examples from my problem). Do other developers just ignore this problem? Please, correct me if I am wrong.
If your concern is that you don't want users to see the page before it is final, you can probably get away with doing the DOM modification straightaway, e.g.:
Test
<script type="text/javascript" src="enhancePage.js"></script>
Because the node in question exists in the DOM before the script is parsed, you can work with it.