How can I keep javascript objects alive in a multi-page app (browser independently)?
I know I can for example write a Chrome extension with a background page that would solve it, but is there a browser independent way for this?
One approach is to have your javascript code load the pages (via 'ajax' calls) and then replace the body of the html, or parts of it. This way, as far as the browser is concerned you're still on the same "page". You'll have to make sure all the links within your website are void and instead of causing a browser page load, they actually trigger a javascript function. This is the way Facebook, for example, manages clicks on its website. See https://stackoverflow.com/a/7425870/562906
As you are using html5 you could use local storage to store JSON representations of your objects:
var json_text = JSON.stringify(your_object, null, 2);
localStorage.setItem("someKey", json_text);
and then to retrieve your item when on the other page:
var your_object = JSON.parse(localStorage.getItem("someKey"));
To use JSON.stringify you may need JSON-js - if the browser does html5 it appears likely that you won't need the third party script.
You can use cookies to pass data between page requests. Apart from that, you always have to reconstruct your objects from the beginning.
Related
I have a website that loads mostly using AJAX calls. The javascript and CSS files are only loaded once when the page first loads.
My issue is that the javascript/CSS can get out of sync with the HTML and server-side code. The page can be using an old versions of the javascript file (from when the page first loaded) while the server-side code and ajax-loaded HTML files always use the latest code and files.
What are some strategies for dealing with this?
I have considered polling the server at set intervals and asking if there is a newer version of the JS. Then, if there is, reloading the page. But, it seems that this can get ugly, with the page suddenly reloading at awkward moments instead of, for example, as the result of a user-initiated call.
Also, there are some changes to the javascript that do not necessarily require that a page be reloaded. For example, the changes might affect a different page/module than the one that the user is on.
Re-loading the javascript with every Ajax call is not viable
I can imagine ugly solutions to this, but thought I'd ask first.
EDIT (in response to comments and suggested answers)
The only way to get the JS back into sync is to reload the page, which then loads the new JS. Adding new JS to an old page won't work as it doesn't get rid of any old functions, listeners, etc. I'm not asking how to reload a page or how to load javascript. I'm asking for a strategy of knowing WHEN to do it, especially in a way that does not seem awkward to the user. Do people incorporate polling to ask if there is a new JS version? Do they then suddenly (from the user's point of view) reload the page? Do they poll even when the tab is hidden? Is this a problem for the server? Where do they keep track of the latest required JS version? Or, do they ask with every AJAX request - hey, should I reload? Did they write a special function for that? Do they keep all new html/server code backwards compatible with the js?
Someone who has dealt with this, how do you do it?
Two possible solutions include
calling $.getScript() to retrieve, update variables at document from at server-side to match variables at document before calling $.ajax(/* settings */) ;
alternatively could use web workers to update original document variables to match server-side variables at beforeSend of $.ajax(/* settings */)
At result of first step of either approach, abort $.ajax() call, call error handlers, notify user, send message to server about error.
var head = document.getElementsByTagName("head")[0],
scripts = {};
function load_script(name){
var myscript = document.createElement('script');
myscript.setAttribute("type","text/javascript");
myscript.setAttribute("src", name);
if (scripts[name]) head.replaceChild(myscript, scripts[name]);
else head.appendChild(myscript);
scripts[name] = myscript;
}
// the first call to load the script code
// and then call if you decide to upgrade a newer version
load_script('js1.js');
load_script('js2.js');
I included Google Analytics (javascript) in my Outsystems website via de eSpace Javascript. Now I want to place the Analytics Key in my Site Properties so I can update it easily for every environment.
How can I use a Site Property in my Javascript?
You can create a site property to store the Tracking ID.
site Property screenshot
Second, you need to create a webblock with an unescaped expression, and add your javascript this way:
weblock expression screenshot
Finally, you just need to drag you weblock to each webpage you want to track.
cheers,
Vera
As far as I know, you cannot use Site Properties in the eSpace JavaScript window. For that, you have to use an escaped expression on a web screen or web block to add your JavaScript code along with the use of Site Properties.
Since you want the same script on all the web screens, I suggest that you add this expression in the Footer web block, so that it will be automatically added to all the web screens you create.
I can understand your use case. If I read it correctly, you're trying to use some JavaScript in one espace, that would be run in every page load, something like an
onLoad(function(){
// your Google Analytics code, but using the value from the site property
})
And in this way, you would be able to update the site property without the need to republish all consumers. Seems like a nice approach :)
On way to be able to achieve this, would be to have your JavaScript to request the key on the fly to the server side, and maybe cache it.
This can be easier or harder depending on the Platform version you're running... But here's a simple way to achieve it.
Add the site property to the espace. Build a page that has no layout, and in the preparation, add a download widget that only downloads the value of your site property. In the same espace, in the espace JavaScript, add an AJAX request to the page I was referring to before, and when you get the response back, start your Google Analytics code.
To be able to use this in every other espace, and in every page, you still need to reference something from the Google Analytics espace though, so that espace JavaScript is run in every page
Hope it helps :)
I'm doing some code that requires actions on multiple sites (get some data switch to another site etc.) in a loop.
I'm trying to do this using setInterval().
Simplified, the task looks like this when launched in a console:
function checkit() {
window.location='http://www.google.pl';
}
var nre = setInterval(checkit,5000);
I have tried launching this script (in more complicated forms through different measures, from bookmarklet, from server side script etc, the interval runs OK in my original code, even does everything what I require in a loop until another page is called (through window.open or window.location). than the loop just seizes to execute.
I'm pretty new to JS (2 days experience) so I'm probbably doing something uterly stupid. Any Advice on how to get this thing going (is this even possible)?
Best regards
The problem you're going to have is that JS doesn't stay from page to page, so once the page changes, that loop goes away. You'll need to have the JS on each page you're wanting to visit to continue flow and even then, the variables are nuked when you change pages.
The only way to circumvent this issue is by storing a serialized object (or JSON string) within the window.name value which is remember across pages and domains within that tab.
I have a project that i can't use the ExternalInterface to get current url from the browser...
So, someone know how i can get current URL from the browser without using ExternalInterface/JavaScript with the Flash/AS3?
Note: I can only use Javascript, HTML, CSS, AS3.
I asked this before on the Mochi forums: https://www.mochimedia.com/community/forum/topic/reliably-find-the-page-url
Long story short, there's no 100% reliable way unless you have some sort of control over where the SWF is placed - loaderInfo.url gives you the swf url, not the page one, and some of the time this can be the address of the preloader SWF (e.g if you make a game that goes onto game sites). You could try JavaScript, but that only works if it's enabled and sometimes you'll get the address of an iFrame, rather than the main page URL. Ditto for calling a PHP file.
Your best best is JS, but keep in mind that it's not perfect
var url:String = ExternalInterface.call("window.location.href.toString");
Note, you can do the same when you're embedding the SWF and pass the value in as a Flashvar
Maybe use flashvars to pass the url to your root on creation (look into swfobject.js)
Or look into: stage.loaderInfo.url
I have an HTML page and a java script file. When I click on a button in my html page I get a Json string in the java script file from the server. The Json string contains data that I want to use in other Html pages, so what would be a good technique to share the json string or object among the html pages, using java script only???
thx
I don't know if that counts as "JavaScript only", but you could use DOM Storage.
window.localStorage.setItem('theData', theData)
That way it even survives closing the window (which you may or may not want).
You could use unique URI REST-style requests for Your data, together with cache headers, so Your browser could use it's native page caching.
PersistJS is a wrapper around the new storage features in modern browsers (LocalStorage,globalStorage,openDatabase, gears,...). It uses feature detection to select the most appropriate storage solution. Including falling back to Cookies/Flash on older browsers.
http://pablotron.org/software/persist-js/
or more details on how it works at: http://pablotron.org/?cid=1557
Using JavaScript only you can go for cookies but they will be limited in size or you can go the new shiny HTML5 Local Storage if you only need to cater modern browsers.
EDIT: You have to open your HTML files through server if you use these, not directly by double clicking!