Changing the behaviour of History.js for HTML4 browsers - javascript

I'm using the history.js plugin (https://github.com/browserstate/history.js/) to give elements on a page a certain unique url when opened.
As expected, this works great in HTML5 browsers, but the plugin isn't quite doing what I need in HTML4 browsers (Internet Explorer, in other words).
Basically, I'm having the same pitfall that is outlined in the documentation for the plugin, as seen here:
These issues are unavoidable if hashes are used.
URLs get polluted if we did not start on the home page
http://www.facebook.com/balupton#!/balupton?sk=info
http://mywebsite.com/page1#/page2
Although, my URLs are not quite as bad as this, other than the hash being thrown in, the url is usable. Removing the suid at the end would also be nice, as it isn't necessary in my case, but it should be fine if that's not possible.
Here is what my URL needs to look like:
http://domain.com/sitename/main/item/109
And this is the result in IE:
http://domain.com/sitename/#main/idea/109?&_suid=13812466306670658...
As far as I could gather from the documentation was that my only option would be to disable the HTML4 fallback, which means that nothing will happen in IE.
I'm wondering if theres a way to just forgo the HTML4 fallback options, but still use the HTML5 solution in it's place (to change the url in the same way it does, just with a different method.. I know that the method used for the HTML5 solution won't work). Or, if there's any other way to alter the way that the HTML4 solution is implemented, to bend it to the needs of this project?
UPDATE: In my own research, I am seeming to find that it is impossible to alter an HTML4 compliant browser's url without using a hash. I'm currently in the process of integrating some workarounds into my project so that our URLs use hashes. I'm still leaving this question open as this isn't really an answer, and I don't even know if I am 100% right.

If it's still needed, the partial answer to cleaner URL for you would be solution below.
Try code below regarding to https://github.com/browserstate/history.js/
History.options.disableSuid
Force History not to append suid

Related

Update query string (no redirect) without HTML 5

Can I update a query string parameter without reload the page? I know that, there are some HTML5 features (history.pushState, etc.) but it doesn't work on many browsers (or browser versions)...
Thanks in advance!
It's not possible without history.pushState.
There's a polyfill using the hash (#) portion of the URL as it can be changed without reloading even on old browsers, but it doesn't cover all use cases (bookmarking and sharing for instance).
You might want to look into history.js for graceful degradation and simplicity of use.

Trying to retire jquery-migrate

Currently I am using $.browser.webkit and $.browser.msie because the input types between the browsers have plenty of unique UI differences that I am having to accommodate for.
Specifically: Chrome changes my range to a slider, IE doesn't; and I have to place a spinner on the IE time type, Chrome covers that. There are others, but these are the ones that I have to deal with the most.
What is the preferred way to test for these differences rather than using the migrate lib's browser test?
(I know I could query the useragent directly, but I would rather query the UI to see if I need to add a spinner, or slider, etc.)
Short answer, mplungjan had an answer that was close but not what I needed. If you look at IE11 vs Chrome where both have a feature that is supported, you may see where they render the support completely differently. So my solution ended up being stay with the migrate lib to detect browser and version, then have my code override the render on browsers that need it.
This means that I will be keeping a dictionary of browsers and implemented features, so my code can intelligently override as dictionary dictates.
As for the case where a feature isn't supported, I will just continue to use the standard test for feature, that has worked and mplungjan has linked to one of the easiest ways to test. Not the best, but the easiest.
Switching to Twitter Bootstrap and Angular.JS UI has reduced some of this oddness, by using other peoples solutions.

HTML5 History API Implementation

This might sound like a duplicate, but I have searched through the forum questions and I haven't found what I was looking for.
So, I have been reading for a while now, and I still cannot decide what to do about the next situation. I'm building a one page website ( not my first ) which requires a smooth User Interface, so I have decide to load pages with AJAX for a better and more friendly navigation.
I have been using : SmartAjax ; for a while and it was good enough for me. It works nicely and I had no problems with it, but with it had problems handling a lot of JavaScript as callback. Also there was a lot of work to do when implementing it through the whole website.
And because now HTML5 is more stable than it was one year ago, and most of it's features are working in most of the browsers ( but some still require a polyfill ), I decided to start using HTML5 History API. A lot of websites use it and it's very easy to do so, but there some aspects I don't understand about it.
Therefore here's what I would like to know about it :
is it supported by all browsers by now, and most important, will touch devices and mobiles support it ?
is there a special library or a framework for it ?
is it safe to use for small websites ( a maximum of 6 pages ) but with a lot of JavaScript ?
does it behave when using it in combination with jQuery Plugins ?
what about hashbang and hashes ? aren't they the same as using History API ? and what are the differences ?
I would appreciate all the help and info I get about the points stated above.
Browser support
Forget it. Not even IE 9 supports history.pushState. Mobile browsers not very safe either. But there is a library (see below) that makes this incompatibility completely transparent to the developer.
Library
Well, in pure HTML 5 environments, the history api is pretty straightforward. For others, the history.js library has gotten quite some attention, plus it offers an automated fallback to the old hash-writing
On Small Websites
Well, you better have your JavaScript and your potential States organised, then. But if so, I see no problem.
History & jQuery & plugins
I have used the two together in a couple of projects now. I have not yet found any problem with using jQuery and jQuery Plugins, except for - of course - the typical issues associated with Injected HTML (i.e. event handlers must be rebound; $(document).ready() might or might not work in some environments, etc).
Hashes vs. history.pushState
The Hash-Notation has been used as a workaround (or nowadays, fallback). It becomes unnecessary when using history.pushState.
What I have found to be the major difference is, that the URL in the address bar is always directly understandable by the server, especially for bookmarking or link-sharing purposes. If you had http://example.org/#/my/fancy/site, then your index page would have to parse the hash (via javascript, as you can't access the hash server-side), and then inject/redirect to my/fancy/site.
However, if using using history.pushState, the Browser's address bar shows http://example.org/my/fancy/site - which is directly routable.
(and, imagine spelling out a hash, or hash-bang URL to someone via phone!)
Hope that clarifies some or your doubts with history! I can strongly recommend History.js as library a of choice.
I would prefer to use HTML5 History for browsers which support it (all current browsers and upcoming IE10), and use just static (non-Ajax) links for older ones. As browsers are updated, your site gets better automatically.
I wouldn't recommend using hash polyfills due to serious disadvantages of hashes (e.g. pointless referers that don't include hash part of URL, thus making stats rather useless).

How facebook overwrite link? [duplicate]

Go to http://www.facebook.com/facebook?v=wall, then click on the info tab. The content will be loaded, and the address bar now becomes http://www.facebook.com/facebook?v=info but the webpage didn't reload.
At first I think it is Ajax, but my question is, how do you change the address bar without reloading? I know I can change anchor (#wall) using JS but querystring (?v=wall), how?
It's using HTML5's new history.pushState() feature to allow the page to masquerade as being at a different URL to that from which it was originally fetched.
This seems only to be supported by WebKit at the moment, which is why the rest of us are seeing ?v=wall#!/facebook?v=info instead of ?v=info.
The feature allows dynamically-loaded pages to be properly bookmarked, exchanged etc between JS-supporting and non-JS-supporting user agents. Because if you as a JS user linked someone to ?v=wall#!/facebook?v=info and their browser didn't support JS and XMLHttpRequest, the page wouldn't work for them. The #! is also used as a tip to search engines to download the non-AJAX version.
#Snoob - I'd appreciate it if you accepted #bobince's answer instead, he's was on the right track about the specifics first here. Since I can't delete/remove this until it's unaccepted I'll update it to be as correct as possible.
At the moment it's a WebKit (Chrome, Safari, etc.) specific thing you're seeing (or rather, not seeing), as #bobince points out in other browsers you can see the real URL in the bar:
http://www.facebook.com/facebook?v=wall#!/facebook?v=info\
Where Chrome just shows:
http://www.facebook.com/facebook?v=info
It makes a bit of sense, given this is how you make AJAX Content crawlable with the Google search engine, so their browser recognizes where the content comes from as well.
Correction on the specifics: Webkit browsers are showing the shortened URL facebook wants using the HTML 5 history features you can see the code here (take a look at the HistoryManager) in this case specifically they're using .replaceState() to replace the URL you went to with the direct one available.
Note: This answer may not be valid later (the WebKit specific bit), as other browsers support HTML5 features more and more this may become outdated quickly.
For MooTools developers I recommend checking out cpojer's mootools-history plugin which provides support for the native history API when available, with a fallback to hashes.
I don't have Facebook so I can't check. But I'm 95% sure that it has to be a full page request, the location bar is unwritable because this would be a very useful feature to absure for phishing websites (instead of http://fakeonlinebank.com it rewrite to http://yourtrustybank). It's probably just so fast that your browser appears to only load that part?
But I'm curious to see if someone will correct me on this, because that would mean they have the answer you do want to hear ;)

How does facebook rewrite the source URL of a page in the browser address bar?

Go to http://www.facebook.com/facebook?v=wall, then click on the info tab. The content will be loaded, and the address bar now becomes http://www.facebook.com/facebook?v=info but the webpage didn't reload.
At first I think it is Ajax, but my question is, how do you change the address bar without reloading? I know I can change anchor (#wall) using JS but querystring (?v=wall), how?
It's using HTML5's new history.pushState() feature to allow the page to masquerade as being at a different URL to that from which it was originally fetched.
This seems only to be supported by WebKit at the moment, which is why the rest of us are seeing ?v=wall#!/facebook?v=info instead of ?v=info.
The feature allows dynamically-loaded pages to be properly bookmarked, exchanged etc between JS-supporting and non-JS-supporting user agents. Because if you as a JS user linked someone to ?v=wall#!/facebook?v=info and their browser didn't support JS and XMLHttpRequest, the page wouldn't work for them. The #! is also used as a tip to search engines to download the non-AJAX version.
#Snoob - I'd appreciate it if you accepted #bobince's answer instead, he's was on the right track about the specifics first here. Since I can't delete/remove this until it's unaccepted I'll update it to be as correct as possible.
At the moment it's a WebKit (Chrome, Safari, etc.) specific thing you're seeing (or rather, not seeing), as #bobince points out in other browsers you can see the real URL in the bar:
http://www.facebook.com/facebook?v=wall#!/facebook?v=info\
Where Chrome just shows:
http://www.facebook.com/facebook?v=info
It makes a bit of sense, given this is how you make AJAX Content crawlable with the Google search engine, so their browser recognizes where the content comes from as well.
Correction on the specifics: Webkit browsers are showing the shortened URL facebook wants using the HTML 5 history features you can see the code here (take a look at the HistoryManager) in this case specifically they're using .replaceState() to replace the URL you went to with the direct one available.
Note: This answer may not be valid later (the WebKit specific bit), as other browsers support HTML5 features more and more this may become outdated quickly.
For MooTools developers I recommend checking out cpojer's mootools-history plugin which provides support for the native history API when available, with a fallback to hashes.
I don't have Facebook so I can't check. But I'm 95% sure that it has to be a full page request, the location bar is unwritable because this would be a very useful feature to absure for phishing websites (instead of http://fakeonlinebank.com it rewrite to http://yourtrustybank). It's probably just so fast that your browser appears to only load that part?
But I'm curious to see if someone will correct me on this, because that would mean they have the answer you do want to hear ;)

Categories

Resources