I have a page that dynamically loads content based on a user pushing a button:
${document).ready(function)
{
$("#myButton").click(function()
{
$("#dynamicDiv").load("www.example.com");
});
}
The dynamic content works fine, I can fetch pages all day long. But after you follow a link to another page, then press the browser back button to come back to the page, the page is completely reset as though no dynamic content had ever been loaded.
I swear I've seen different behavior before, but maybe I'm insane. Shouldn't the browser preserve the state of the page, rather than re-rendering it?
EDIT:
By the way, I'm using Play! framework, if that has any bearing on this.
The browser loads the page as it was first received. Any DOM modifications done via javascript will not be preserved.
If you want to preserve the modifications you will have to do some extra work. After you modify the DOM, update the url hash with an identifier that you can later parse and recreate the modification. Whenever the page is loaded you need to check for the presence of a hash and do the DOM modifications based on the identifier.
For example if you are displaying user information dynamically. Every time you display one you would change the url hash to something like this: "#/user/john". Whenever the page loads you need to check if the hash exists (window.location.hash), parse it, and load the user information.
Implementing browser back functionality is hard.
It gets easier when you use a plugin like jquery.history.js.
http://tkyk.github.com/jquery-history-plugin/
A technique I use for this is to serialize state to JSON, store it in the hash string, and then read it back when the page is navigated back to. This has been tested in IE10+, Firefox, Chrome.
Example:
// On state change or at least before navigating away from the page, serialize and encode the state
// data you want to retain into the hash string
window.location.hash = encodeURIComponent(JSON.stringify(myData));
// If navigating away using Javascript, be sure to use window.location.href over window.location.replace
window.location.href = '/another-page-url'
....
// On page load (e.g. in an init function), if there is data in the #hash, overwrite initial state data
// by decoding and parsing the JSON string
if (window.location.hash) {
// Read the hash string omitting the # prefix
var hashJson = window.location.hash.substring(1);
// Restore the deserialized data to memory
myData = JSON.parse(decodeURIComponent(hashJson));
}
epignosisx and Malcolm are both right. It's also known as "deep linking". We used the JQuery Address Plugin to deal with this in a recent Play application.
http://www.asual.com/jquery/address/
Related
This code toggles the color of an element whenever you click on it. But how can I send a GET request with query string ?toggle=True on the first toggle and ?toggle=False on the second one?
Ow, I can see it appearing in Firebug, but not in the url of the page. Any idea why?
Making a request and changing the URI in the address bar are two different things unless you cause the browser to load a completely new page.
If you want to do that, then you should forget about using client side JavaScript and move your logic server side and use a regular link.
In the server side logic, the value of the query string argument would be used to determine the class of the div (which is used to set the style) and the href of the link (i.e. if it has True or False in the query string).
If you want to avoid loading a new page, then you are looking at two separate steps.
The first one you already have (the changing of the style using JS).
The rest gets more complicated…
First you need server side logic so that True/False in the query string will set up the initial state of the page correctly. This will be the same as the logic described for the previous method.
Then you need to update the URI so that it matches the one that would load the page in the state you are altering the current page into. This is done using the History API (pushState and friends). There are more details on the subject on this question.
If you want to notify the server of the change, then you'll need to use jQuery.get, as well as updating the page and changing the URI in the address bar. To be efficient, you should probably add an additional query string argument (so you can tell if it from Ajax from that a normal page load) and have the server return a simple acknowledgement rather than the whole HTML document when it sees that argument.
Just use jQuery's get method to do so or do it yourself in your toggle functions.
A pragmatic yet pretty basic solution may be to use a local variable as a counter.. If the counter is even, send True, if odd, send False.
Increment counter on each click :)
Maybe that's not a good question but I'm wondering if it would be somehow easily and quickly (with just 1 function perhaps?) possible to change ALL links on website from refreshing webpage to loading the URL that user clicked via AJAX?
My website has standard links everywhere but if you want to have mobile application for iPhone out of it you need to use AJAX everywhere (and perhaps HTML5 History API) because any link will open Safari browser.
Do you think there's any way to quickly convert every single link to delete current source code and load brand-new page without refreshing browser window? Or does it require manual coding and separate functions for every single set of links?
Example:
jQuery(document).on('a', 'click', function(){
// STEP1: AJAX call that will make PHP download page from link
// STEP2: Delete current source code and load new one (in this case including deletion of this function itself)
});
Do you think it would be possible or are there any pitfalls here?
I've done something similar to this. It's possible, but you may have to change a couple of things on server side.
In my case, i had some links with href = #, some of them had click triggers, so i wanted to keep them out.
In this function i check every link without href = #, and if they don't have a click event, i bind ajax.
bindAjaxLinks: function() {
$('a[href!="#"]').each(function() {
var eventObj = $(this).data('events');
if (!eventObj || !eventObj.click) {
// not a javascript link, do your thing
var link = $(this).attr('href');
if (link) {
$(this).click(function(event) {
event.preventDefault();
// do your ajax calling here.
});
}
}
});
Some considerations: In my case, i added an extra parameter, something like isAjax to every request i made with this function, and in backend i sent only a part of whole page(without head and some other markup). And later i replaced what is visible to user with this new html.
This caused a problem: if server responded with a redirect, i got the whole page, which i didn't want, so i made sure this isAjax parameter is kept after redirects, and that solved this problem.
Is there a way when Page change location to keep some HTML Element's.
Like a div that will not be re-rendered but keep it's state.
You can find and example like that at Facebook Chat ,you can see that the Chat window does not change it's location or InnerHtml when you navigate to another page.
PS : I have no clue where to start so any documentation would be appreciated.And it would be nice if solution would be XHTML not HTML5
I don't know exactly how facebook chat works, but I do know all chat messages are stored in a database, so you can access them later via messages.
My assumption would be that a Session variable is set letting facebook's UI know what chats you have open, or perhaps its stored in the database as well. In either case, you'd have to use some outside script in order to do this. For sake of ease lets say you'll use PHP, and you'll store the data in a SESSION variable.
/* Storing the variable */
$users = array('user123', 'user456', 'user789');
$_SESSION['chat_windows_open'] = $users;
/* Retrieving the values */
foreach($_SESSION['chat_windows_open'] as $chat) {
/* Use $chat to get the username, query the DB for
the message content, and echo it in whatever form you
wish. */
}
When window.location changes, the page is automaticaly, entirely re-rendered. So, from this point of view, the answer is no. However, this effect can be obtained by using AJAX. Use ajax to make requests to the server while the page does not reload or changes location(window.location is always the same). Here's a good link to start with AJAX:
http://www.w3schools.com/ajax/default.asp
If you still want the page to change it's location, after you've made your ajax request and updated the content on the page, you can use javascript's history.pushState function. However you will have to find a way to make it cross browser(aka. make it work in IE).
I want to make a page with a lot of Javascript interactions. However, while a user navigates through the page the URL must change too. So, when the user shares the URL or saves it, it can lead him to the actual state he was.
How can I do that?
Examples:
myapp.com/page1
myapp.com/page2
pushState, as seen on github
Answered by this SO question: Change the URL in the browser without loading the new page using JavaScript
The only part of the url (or location) that you can change without reloading the page, is the hash. That is the part behind the #. Many ajax enhanced applications make use of this, including Twitter. You can change this hash on the go, and interpret the hash tag on page load to initialize the page to the correct state.
Set this value: window.location.href
window.location.href = "myapp.com/page2";
Still now I knew Its not Possible to change the contents of location bar without changing the page (and Yes I am not talking about #). I've recently noticed github.com. How they are doing that on their site ? they can easily get an event when user clicks on Browser's back or next button. dojo.back also have this feature. But how to change the addressbar with javascript without leaving the page ?
There are two ways:
HTML5's pushState() function. Facebook and Github use this, for example. It allows you to modify the complete URL and fires event handlers when the history state changes. Mozilla has a good overview.
The old variant is to use the hash part of the URL (this is what Twitter does). This means that you change window.location.hash, monitor it for changes and, based on the value of that hash, load the appropriate content. However, this means that when the user requests, say, http://twitter.com/#!/27c3/status/18331752900591616, only the part before the hash sign is requested form the webserver, everything after the hash is only the client's business. This means that the server can not yet decide what content to hand to the client.
try dojo.hash
What you're referring to on GitHub is the # (hash). When you right click on a line number, it adds the number to your hash.
window.location.hash = 'HELLO';
Put that in a page to try it out. It's not possible to change window.location without the page reloading. The back button stuff is a little trickier, but Dojo is your best bet for that. jQuery doesn't provide this. Dojo has pretty clean code though, so you should be able to reverse engineer their functions (if you chose to include that functionality into your own library).
You'll also notice Google is doing the same with: http://code.google.com/p/digitalxero/source/browse/#svn%2Ftrunk%2Flocale%2Fde
If you click on folders (left), it changes the hash, and provides different content.