Problem with IE and setInterval() not refreshing/updating - javascript

I'm using JavaScript/Jquery to make a page auto-update with a value from a database, although it doesn't seem to update in Internet Explorer. It works fine in FireFox & Chrome. Can anyone explain what's wrong? It looks like IE is just displaying a cached version of the page. How can I prevent this happening? Thanks.
function updateComm() {
var url="commandSys.php";
jQuery("#theElement").load(url);
}
setInterval("updateComm()", 1000);

Try disabling the cache with ajaxSetup
$.ajaxSetup ({
// Disable caching of AJAX responses */
cache: false
});
function updateComm() {
var url="commandSys.php";
jQuery("#theElement").load(url);
}
setInterval(updateComm, 1000);
Alternatively, you can manually just append a +new Date to url so it appends a query string to prevent caching.
Alternatively, disable caching on the server-side.

Your php page is cached. Has nothing to do with the interval. Set the right caching headers on the page.

Related

IE is not refresh after call the download function

In the jsp, I use javascript, jquery and json to call a function for download, once the the download is finished, it will return the the current page.
However the problem is although the download is complete, I can able to download and view the file. In the screen, it still show the message indicate it is downloading.
I read this post, the accepted solution mentioned to disable the cache with ajaxSetup. I read my code, I have already include it in the code, however the Internet Explorer still not return to proper page when the download finished. Is there any method I can use to solve the problem. Thank you.
function startDownload() {
$.blockUI({ message: '<h1>Downloading, please wait...</h1>' });
var i = setInterval(function() {
$.ajaxSetup({ cache: false });
$.getJSON("ThePage/downloadProgress?jsoncallback=?",function(download_token) {
if (download_token.fileDownloadToken == "finished" ) {
$.unblockUI();
clearInterval(i);
}
});
}, 1000);
}
Update
I mentioned it occurs on IE because our company is mainly using IE for the web browser. So I intend to make to code works on the IE first. Sorry for the inconvenience that I have made.

Why this polling stops working after idling for some time?

I am using AngularJS to constantly poll for new data through HTTP POST. An alert will be sent when new data is received. The code which is inside a controller looks something like this;
var poll = function() {
$http.get('phones.json').success(
function(data)
{
new_val = data.val;
if ( (new_val!== old_val) )
{
$window.alert("AlertEvent");
}
old_data = new_val;
$timeout(poll, 500);
}
);
};
poll();
This code works when the html page is refreshed. Working means when phones.json is changed, an alert will appear. However, if I leave the page on for, say 30 minutes, and come back later, it stops working. I have to refresh the page to get it working again.
What else did I miss out? What did I do wrong? Could it due to some caching mechanism?
Thank you very much.
EDIT: I found the cause. It is indeed due to the browser reading from cache. I can see this using Chrome Developer tools. How can this caching be disabled for this html page only?
You may be able to bust the cache by doing something like this:
$http.get('phones.json?v=' + Date.now())
Depending on how your back-end is set-up you may need to adjust it to accept that.

How to remove caching with javascript code?

I have small problem with my recent project build in HTML and Javascript + jQuery only. I would like to prevent page caching as I need to refresh some area of page with some time interval.
If I reload the page, then we can set the "no-cache" META tag into header. But I am not going to reload the page and though jQuery calls XML files with AJAX those javascript files are getting cached and Memory overhead occurs. Because of this my FireFox crashes and memory usages increase up to 2 GB.
Can any one suggest me something fruitful so that I can solve memory overhead problem and running my application over browser smoothly.
function refresh() {
$('#table_info').remove();
$('#table').hide();
if (refreshTimer) {
clearTimeout(refreshTimer);
refreshTimer = null ;
}
$.ajax({
document.getElementById('refresh_topology').disabled=true;
$('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
$("#topo").hide();
$('#root').remove();
show_topology();
});
}
This is the code and show_topology() is been called frequently to make different status of Topology everytime.
disable jquery ajax cache:
$.ajax({cache: false});

How to reliably send a request cross domain and cross browser on page unload

I have javascript code that's loaded by 3rd parties. The javascript keeps track of a number of metrics, and when a user exits the page I'd like to send the metrics back to my server.
Due to XSS checks in some browsers, like IE, I cannot do a simple jquery.ajax() call. Instead, I'm appending an image src to the page with jquery. Here's the code, cased by browser:
function record_metrics() {
//Arbitrary code execution here to set test_url
$esajquery('#MainDiv').append("<img src='" + test_url + "' />");
}
if ($esajquery.browser.msie) {
window.onbeforeunload = function() { record_metrics(); }
} else {
$esajquery(window).unload(
function(){ record_metrics(); }
);
}
FF aborts the request to "test_url" if I use window.onbeforeunload, and IE8 doesn't work with jquery's unload(). IE8 also fails to work if the arbitrary test_url setting code is too long, although IE8 seems to work fine if the is immediately appended to the DOM.
Is there a better way to solve this issue? Unfortunately this really needs to execute when a user leaves the page.
For posterity's sake, here's what I ended up doing:
if ($.browser.msie) {
window.onbeforeunload = function() { $('#div1').append("<img src='record_call' />");
} else {
$(window).unload(
if ($.browser.webkit) {
$.ajax(url:record_call, async:false);
} else {
$('#div1').append("<script src='record_call' />");
}
);
}
I found that IE works appending an img, but not a script, possibly because the script is more resource intensive and it cuts out before trying to load it. For webkit, appending a script sometimes works, but appending an image never seemed to work. Lastly, I default to the script (mainly for FF) because older browser versions all seem to play well with it. IE blocks the AJAX call used by webkit because of xss.
In addition, IE never works with jquery's unload function, and the other browsers don't work with onbeforeunload, so those have to be cased. This certainly isn't a pretty solution, but it works most of the time.
A heads up for those trying to use Agmin's method above: When you use jQuery's append() method to append a script tag, the internal jQuery wiring uses jQuery.ajax() to execute the script, so if the script tag you're appending is on a different domain, Same Origin Policy will prevent the script from being executed.
From what I remember, some browsers only accept a text string for the onbeforeunload result. Try something more like this:
jQuery(window).bind('beforeunload', function() { record_metrics(); return ''; } );
Not sure, but that might even work for all browsers, but I'm only guessing at this point.
p.s. also see How can I override the OnBeforeUnload dialog and replace it with my own?
You should take a look at easyXDM library
http://easyxdm.net/
I think it will make your work easy regarding the limitation set in place by the Same Origin Policy

How can I detect changes in location hash?

I am using Ajax and hash for navigation.
Is there a way to check if the window.location.hash changed like this?
http://example.com/blah#123 to http://example.com/blah#456
It works if I check it when the document loads.
But if I have #hash based navigation it doesn't work when I press the back button on the browser (so I jump from blah#456 to blah#123).
It shows inside the address box, but I can't catch it with JavaScript.
The only way to really do this (and is how the 'reallysimplehistory' does this), is by setting an interval that keeps checking the current hash, and comparing it against what it was before, we do this and let subscribers subscribe to a changed event that we fire if the hash changes.. its not perfect but browsers really don't support this event natively.
Update to keep this answer fresh:
If you are using jQuery (which today should be somewhat foundational for most) then a nice solution is to use the abstraction that jQuery gives you by using its events system to listen to hashchange events on the window object.
$(window).on('hashchange', function() {
//.. work ..
});
The nice thing here is you can write code that doesn't need to even worry about hashchange support, however you DO need to do some magic, in form of a somewhat lesser known jQuery feature jQuery special events.
With this feature you essentially get to run some setup code for any event, the first time somebody attempts to use the event in any way (such as binding to the event).
In this setup code you can check for native browser support and if the browser doesn't natively implement this, you can setup a single timer to poll for changes, and trigger the jQuery event.
This completely unbinds your code from needing to understand this support problem, the implementation of a special event of this kind is trivial (to get a simple 98% working version), but why do that when somebody else has already.
HTML5 specifies a hashchange event. This event is now supported by all modern browsers. Support was added in the following browser versions:
Internet Explorer 8
Firefox 3.6
Chrome 5
Safari 5
Opera 10.6
Note that in case of Internet Explorer 7 and Internet Explorer 9 the if statment will give true (for "onhashchange" in windows), but the window.onhashchange will never fire, so it's better to store hash and check it after every 100 millisecond whether it's changed or not for all versions of Internet Explorer.
if (("onhashchange" in window) && !($.browser.msie)) {
window.onhashchange = function () {
alert(window.location.hash);
}
// Or $(window).bind( 'hashchange',function(e) {
// alert(window.location.hash);
// });
}
else {
var prevHash = window.location.hash;
window.setInterval(function () {
if (window.location.hash != prevHash) {
prevHash = window.location.hash;
alert(window.location.hash);
}
}, 100);
}
EDIT -
Since jQuery 1.9, $.browser.msie is not supported. Source: http://api.jquery.com/jquery.browser/
There are a lot of tricks to deal with History and window.location.hash in IE browsers:
As original question said, if you go from page a.html#b to a.html#c, and then hit the back button, the browser doesn't know that page has changed. Let me say it with an example: window.location.href will be 'a.html#c', no matter if you are in a.html#b or a.html#c.
Actually, a.html#b and a.html#c are stored in history only if elements '<a name="#b">' and '<a name="#c">' exists previously in the page.
However, if you put an iframe inside a page, navigate from a.html#b to a.html#c in that iframe and then hit the back button, iframe.contentWindow.document.location.href changes as expected.
If you use 'document.domain=something' in your code, then you can't access to iframe.contentWindow.document.open()' (and many History Managers does that)
I know this isn't a real response, but maybe IE-History notes are useful to somebody.
Firefox has had an onhashchange event since 3.6. See window.onhashchange.
I was using this in a react application to make the URL display different parameters depending what view the user was on.
I watched the hash parameter using
window.addEventListener('hashchange', doSomethingWithChangeFunction);
Then
function doSomethingWithChangeFunction () {
let urlParam = window.location.hash; // Get new hash value
// ... Do something with new hash value
};
Worked a treat, works with forward and back browser buttons and also in browser history.
You could easily implement an observer (the "watch" method) on the "hash" property of "window.location" object.
Firefox has its own implementation for watching changes of object, but if you use some other implementation (such as Watch for object properties changes in JavaScript) - for other browsers, that will do the trick.
The code will look like this:
window.location.watch(
'hash',
function(id,oldVal,newVal){
console.log("the window's hash value has changed from "+oldval+" to "+newVal);
}
);
Then you can test it:
var myHashLink = "home";
window.location = window.location + "#" + myHashLink;
And of course that will trigger your observer function.
Another great implementation is jQuery History which will use the native onhashchange event if it is supported by the browser, if not it will use an iframe or interval appropriately for the browser to ensure all the expected functionality is successfully emulated. It also provides a nice interface to bind to certain states.
Another project worth noting as well is jQuery Ajaxy which is pretty much an extension for jQuery History to add ajax to the mix. As when you start using ajax with hashes it get's quite complicated!
var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123
function TrackHash() {
if (document.location != page_url + current_url_w_hash) {
window.location = document.location;
}
return false;
}
var RunTabs = setInterval(TrackHash, 200);
That's it... now, anytime you hit your back or forward buttons, the page will reload as per the new hash value.
I've been using path.js for my client side routing. I've found it to be quite succinct and lightweight (it's also been published to NPM too), and makes use of hash based navigation.
path.js NPM
path.js GitHub
SHORT and SIMPLE example
Click on buttons to change hash
window.onhashchange = () => console.log(`Hash changed -> ${window.location.hash}`)
<button onclick="window.location.hash=Math.random()">hash to Math.Random</button>
<button onclick="window.location.hash='ABC'">Hash to ABC</button>
<button onclick="window.location.hash='XYZ'">Hash to XYZ</button>

Categories

Resources