Ajax - How to change URL by content - ajax

I'll explain:
I have a picture gallery, the first page is display.php.
Users can flip through pictures using arrows, when you click an arrow it sends an Ajax request to retrieve the next picture from the db. Now I want the URL to change according to the picture displayed.
So if the first picture is:
www.mydomain.com/display.php?picture=Paris at night
I'll flip to the next one and the URL would be
www.mydomain.com/display.php?picture=The Big Ben
How do I do this?

The trick here are uri's with an anchor fragment.
The part before '#' points to a resource on the internet, and after normally designates to a anchor on the page.
The browser does not refresh if the resource is the same but moves to the anchors position when present.
This way you can keep the convenience of browser history from a usability point of view while replacing certain parts on the page with ajax for a fast and responsive user interface.
Using a plugin like jQuery history (as suggested by others) is really easy: you decorate certain elements with a rel attribute by which the plugin takes care of the rest.
Also kinda related to this topic is something called 'hijax', and it's something I really like.
This means generating html just like you would in the old days before ajax. Then you hijack certain behavior like links and request the content with ajax, only replacing the necessary parts. This in combination with the above technique allows really SEO friendly and accessible webpages.

You can use the jQuery history plugin for example.

changing the search of the url will load the changed url.
See also: stackoverflow, javascript changing the get parameter without redirecting

Do you really want to use AJAX here?
A traditional web request would work like this...
User navigates to display.php
User clicks "next" and location is updated to "display.php?picture=Big-Ben"
Big Ben is shown to user, along with a link to "display.php?picture=Parliment"
User clicks "next" and location is updated to "display.php?picture=Parliment"
And so on.
With AJAX, you essentially replace the GET with a "behind the scenes" GET, that just replaces a portion of your page. You would do this to make things faster... for example...
User navigates to display.php
User clicks "next" and the next image location is obtained using an AJAX request
The image (and image description) is changed to the next image
What you are suggesting is that you retrieve the "next url" using AJAX and then also perform a GET on the whole page. You would be much better off sending the "next" image when you send each page and not using AJAX at all.

this best describes everything i think: http://ajaxpatterns.org/Unique_URLs

Related

How do Big sites prevent the loading circle on tabs from showing?

Okay I do not know how to explain this to you, It may be just my internet, or maybe my site is slower, or they really have a technique for doing this.
If you visit Facebook, Reddit, Youtube, Twitter, and if you click on links or any actions on those websites, the url changes but the browser tab doesn't show any loading circle.
How do they do that?
I am pretty sure my website is fast enought and at times it loads even faster than the bigger sites, but mine shows the loading circle on the browser tab.
Okay so I found the answer. Here is the technique for changing the url without reloading the page.
Updating address bar with new URL without hash or reloading the page
How do I modify the URL without reloading the page?
I am still trying to figure out though how to redirect the actual page without reloading the entire page. I am guessing they are loading it via ajax or something similar upon url change. I'll update this once I figure it out.
Edit: I am currently working on this feature for my site. The technique is to use ajax to load the content based on the url. I'll update this thread more as I update my site with this feature.
Edit 2: Damn, you will probably face the same problem I had trying to detect the url change without using onhashchange. If so, here you go:
How to detect URL change in JavaScript
This literally took me 4 hours just to figure that one out.....
Edit 3: I have now integrated this feature on my site. You can check it at
Grandweb
It is quite simple, but lots of work in appending the content once retrieved via ajax. So here is the process:
I am using pushState(); to change the url without reloading the page.
var url = $(this).attr('href');
var split_url = url.split('/');
var new_url = url.replace('https://grandweb.net/','');
window.history.pushState("object or string", "Title", "/write");
Using 'mouseup' was a bad idea, I changed my mind.
I then have to trigger the first function using 'mouseup' to retreieve the content via ajax, and then listen to succeeding onpopstate() for the next ones, because some mouse actions such as Mouse 4 or Mouse 5 are bound to the browser's Back and Forward button, and does not trigger via 'mouseup'.
$(window).on('mouseup', function(evt) {
get_content();
}
window.onpopstate = function(event) {
get_content();
}
The first one is responsible for triggering the function on first try because onpopstate only listens only when the browser's history API is populated.
Using mouseup was a bad idea, basically, don't use it unless you really want to detect mouse action from anywhere on the document.
I instead use the anchor tags/links to trigger the first function for retrieveng content.
example:
<a class="dynamic_btn" href="website.com/post">Home</a>
then
$(document).on('click','.dynamic_btn',function(e){
e.preventDefault();
get_content();
});
Using onhashchange is possible IF you have hashes on your url. I do not use hashes on my url so basically onhashchange is useless in my use case, unless I do not know something.
After retrieving the contents, I append them via creating DOM elements to existing containers from the page.
This is much easier to do if you are planning to change few elements or containers in your pages. If you plan on doing this to change a full page layout, goodluck. It's doable, but it's a really pain in tha *ss.
Upon observing Facebook, I learned that they do not implement this technique in all of their links/features. It makes sense because this is harder to maintain most especially because most of the work here is being done client side. It is very nice though because the page doesn't load.
I have implemented it on a few 'essential' functions of my website such as the viewing of posts and returning to the homepage. I can implement it on the whole site, but I am still deciding on that. That is all, thank you very much for reading internet stranger.

Dynamically change address in the URL bar

Okay, I have seem similar questions around Stack sites, yet some of them were asked as far back as four years ago, so given the recent developments in HTML, jQuery and PHP, I'm convinced there are new workarounds.
Suppose I have a domain www.mysite.co.uk, which has an ajax that, once triggered, clears the default on-load content #0, and replaces it with content #1.
(This content can also be accessed by going to www.mysite.co.uk/1)
Then a user may trigger another ajax that will clear content #1 and populate with content #2.
This is where I have a problem. Because clicking the Back button will not send the user back to content #1 (in fact if there is no history, the Back button is greyed out).
What I want to do, is when user triggers an ajax that populates the page with content #3, I also want it to change the URL bar to www.mysite.co.uk/3, so this way the same content will load when the page is refreshed, instead of going back to the default content #0.
Hope this makes sense.
I know that www.asana.com do it, but not sure how.
I'm already developing grey hair by trying to sort this out.
Edit: I've seen some examples where they do that by #anchoring, or with a ?get_variable, but I'd rather do it by changing the URL-proper, like Asana.com does it.
You're looking for JavaScript's pushState() method in the history API:
Manipulating the browser history
Note: you can check compatibility with browsers on Can I use...

"facebook comment id" added to url - inconveniently

A user comments on the page, the comment is posted to their facebook wall. When another facebook user clicks the link to see the comment it links back to the page but with a massive string of numbers on the end.
http://canofclouds.com/thought/?fb_comment_id=fbc_10150505683457013_20914817_10150507783662013#55
The original url was: http://www.canofclouds.com/thought/#55
This is all fine so far though, until the user clicks a button to go to
http://www.canofclouds.com/thought/#56
Instead, it goes to:
http://canofclouds.com/thought/?fb_comment_id=fbc_10150505683457013_20914817_10150507783662013#f25e670a6c
Which is not good - because it doesn't exist. Ideally it would just go to http://www.canofclouds.com/thought/#56
Normally, when the user clicks the next button a flurry of javascript grabs the hash key (in this case #55) then adds 1 to it (to make #56 - yay) and executes an ajax call to grab the new content. This facebook stuff is making things a little complicated though.
Any ideas?
Edit: Even more ideally i could disable the 'fb comments id' altogether.
You shouldn't use hash keys to link to your page. You should use a canonical URL to do so.
There are a few questions here on stack overflow about how to deal with this.
The only way around it if you choose not to make canonical urls, is to do URL Rewriting at the network or web server level.

Should I load an entire html page with AJAX?

My designer thought it was a good idea to create a transition between different pages. Essentially only the content part will reload (header and footer stay intact), and only the content div should have a transitional effect (fade or some sort). To create this sort of effect isn't really the problem, to make google (analytics) happy is...
Solutions I didn't like and why;
Load only the content div with ajax: google won't see any content, meaning the site will never be found, or only the parts which are retrieved by ajax, which arent't full pages at all
show the transitional effect, then after that 'redirect' the user to the designated page (capture the click event of a elements): effect is pretty much the same as just linking to another page, eg. user will still see a page being reloaded
I thought of one possible solution:
When a visitor clicks a link, capture the event, load the target with ajax, show the transitional effect in the meantime, then just rewrite the entire document with the content fetched with the ajax request.
At least this will work and has some advantages; the page reload will look seamless, no matter how slow your internet connection is, google won't really mind because the ajax content is a full html page itself, and can be crawled as is, even non-javascript browsers (mobile phones et al.) won't mind, they just reload the page.
My hesitation to implement this method is that i would reload an entire page using ajax. I'm wondering if this is what ajax is meant to do, if it would slow things down. Most of all, is there a better solution, eg. my first 'bad' solution but slightly different so google would like it (analytics too)?
Thanks for your thoughts on this!
Short answer: I would not recommend loading an entire page in this manner.
Long answer: Not recommended. whilst possible, this is not really the intent of XHR/Ajax. Essentially what you're doing is replicating the native behaviour of the browser. Some of the problems you'll encounter:
Support for the Back/Forward
button. You'll need a URI # scheme
to solve.
The Browser must parse
the entire page through AJAX.
This'll slow things down. E.g. if
you load a block of HTML into the
browser, then replace the DOM with
it, only then will any scripts, CSS
or images contained therein begin
downloading.
Memory - the
browser's not changing pages. Over
time (depending on the browser), I'd
expect the memory usage to increase.
Accessibility. Screen readers
will need to be notified whenever
the page content is updated. Might
not be a concern for you but worth
mentioning.
Caching. Browser
would not know which page to cache
(beyond the initial load).
Separation of concerns - your View
is essentially broken into
server-side pieces to render the
page's content along with the static
HTML for the page framework and
lastly the JS to combined the server
piece with the browser piece.
This'll make maintenance over time
problematic and complex.
Integration with other components -
you're already seeing problems with
Google Analytics. You may encounter
issues with other components related
to the timing of when the DOM is
constructed.
Whether it's worth it for the page transition effect is your call but I hope I've answered your question.
you can have AJAX and SEO: Google's proposal .
i think you can learn something from Gmail's design.
This may be a bit strange, but I have an idea for this.
Prepare your pages to load with an 'ifarme' GET parameter.
When there is 'iframe' load it with some javascript to trigger the parent show_iframe_content()
When there is no 'iframe' just load the page, with a hidden iframe element called 'preloader'
Your goal is to make sure every of your links are opened in the 'preloader' with an additional 'iframe' get parameter, and when the loading of the iframe finishes, and it calls the show_iframe_content() you copy the content to your parent page.
Like this: Link clicked -> transition to loading phase -> iframe loaded -> show_iframe_content() called -> iframe content copied back to parent -> transition back to normal phase
The whole thing is good since, if a crawler visit ary of your pages, it will do it without the 'iframe' get parameter, so it can go through all your pages like normal, but when you use it in a browser, you make your links do the magic above.
This is just a sketch of it, but I'm sure it can be made right.
EDIT: Actually you can do it with simple ajax, without iframe, the thing is you have to modify the page after it has been loaded in the browser, to load the linked content with ajax. Also crawlers should see the links.
Example script:
$.fn.initLinks = function() {
$("a",this).click(function() {
var url = $(this).attr("href");
// transition to loading phase ...
// Ajax post parameter tells the site lo load only the content without header/footer
$.post(href,"ajax=1",function(data) {
$("#content").html(data).initLinks();
// transition to normal phase ...
});
return false;
});
};
$(function() {
$("body").initLinks();
});
Google analytics can track javascript events as if they are pageviews- check here for implementation:
http://www.google.com/support/googleanalytics/bin/answer.py?hl=en-GB&answer=55521

load a new page using ajax

I am new to ajax and i wanted to know if we can load a complete new page and not just a part of it using ajax. Please give a small example script for understanding if this is possible. Here i am trying to display only one url to user while i change from one page to another when he clicks on any of the links in the page.
You can of course request for a new page and load it via body.innerHTML = ajax.responseText;
I would strongly recommend against this though for reasons outlined in this post: Why not just using ajax for Page Requests to load the page content?
The whole premise really is that with
AJAX you don't need to reload the
whole page to update a small
percentage of that webpage. This saves
bandwidth and is usually much quicker
than reloading the whole page.
But if you are using AJAX to load the
whole page this is in fact
counterproductive. You have to write
customised routines to deal with the
callback of the AJAX data. Its a whole
lot of extra work for little to no
increase in performance.
General rule for where to use AJAX: If
your updating >50% of your page, just
reload, else use AJAX.
You will not only need to request for the new page, but then also take care of ensuring the old styles on the current page are removed and don't interfere with the new page. Theres all sorts of problems associated with what your trying to do. It's possible, but I recommend not to do it.
edit: actually you might be able to just do document.write(ajax.responseText) which should take care of overwriting everything in the document, including css styles etc. Though still don't recommend it.
When you're finished with processing the AJAX request simply use this JS line:
window.location.replace('<URL of the new page>');
This has exactly the effect of loading the new page via
....
When you make an AJAX request, a request goes off and brings you the contents of the URL that you have requested. Now technically you can do whatever you like with the contents (which could be HTML), you can replace any element within the DOM with it. Be careful however of replacing EVERYTHING on the page, you are more likely just going to want to replace what is within the tags.
If what you want to do is show one URL for multiple pages, AJAX is overkill. Why not just use an IFRAME?
This could be useful if your page was unsure if it was expecting back errors to be inserted onto the page or a "new" submission confirmation page. This can be used when you want to put a validation servlet (or whatever) in front of the submission servlet (or whatever). If the page always hits the validation servlet, you hide the submission servlet which actually performs the data update. In the case where the validation passes, forward to the submission servlet. The user never knows what happened in the background.
When the page gets a response back you could just look at the first portion of the response text and determine if it had a keyword set by the server, which means this is a new page. Remove the keyword from the text, and do document.write(ajax.responseText); as described previously. Otherwise insert the response text into your errorBox div and let the user retry submission.

Resources