I'm trying to monitor my URL hash (a.k.a. fragment) using the onhashchange event so that I can make appropriate ajax calls based upon the parameters I'm storing in the hash. Unfortunately, there is something unexpected changing my hash. In all of my code, there is only one place that where I use window.location.hash and it is simply checking the value of the hash, not changing it. I know that the back and forward buttons can change the hash, but I'm not touching them. How do I find where the hash change is coming from?
Update
Ok... figured it out. And yes, I'm a dummy, but I leave my findings here for those as dumb as I. I was looking for something programmatic changing my hash, but what was really happening was that I was clicking on an anchor with href="#". There is an event handler hooked to these, and I set the return value to false and that prevented it from changing the URL.
Links that target internal anchors change the hash. For example:
Contact Us
Clicking that would change the hash to #contact.
Also, if you're using any third-party javascript libraries, it's possible that some code in there might be changing it.
What does the hash change to? From what? And When? If you can identify the exact circumstances that trigger the change, that should give you some idea what might be changing it.
Related
I try to use the window.history.replaceState method just to show the URL shown in the browser.
window.history.replaceState("","","newurl.php");
Well, this works well and changes the URL. But what is this "State" that I set to "" here? And how should I change my code if I simply want to be the State as before? (As I said... I just wanted to change the URL and this works well, not to change the state...)
.replaceState() a way to associate some data (any data that can be structured cloned) with the current location - without reloading the page. There's also pushState, that does the same thing, but you can also use the browser's back button to go back to the previous displayed url / state.
If you don't use these for something else, you don't have to care about the state you set (it's only visible to your website).
If you, on the other hand, do use states, and don't want to change it, you can set the same state as it was before. You can get the current state with history.state:
window.history.replaceState(window.history.state,"","newurl.php");
Is there any way to do something like this: $(window).on("hashchange", doSomething); but detect document.location.search change?
This was already asked in On - window.location.hash - change?. In a nutshell, there is no perfectly clean way to do this in JavaScript; you would need to be checking the location every now and then. Some frameworks and libraries will give you a nice abstraction layer over this but internally, they just keep polling the location.
Unfortunately, Lucas' answer is incorrect - you can use the JavaScript History API to modify the current URL without reloading the page.
The hash and the search tag are having different implementation. When the search string got changes the whole page got reloaded but not in the case of hash. So if you want to do some processing on href change then you can use the onbeforeunload event handler.
You can use the beforeunload event to trigger your code to run prior to navigation... If you need something more specific (e.g., only navigations initiated in your code), then I recommend that you factor out code changing window.location into a separate function, and add a hook for your custom logic.
For better understanding you may want to look at Ben Nadel's post in regard to doing this, it may be exactly what you're looking for.
Differently from what happens with hash, if your search value changes due to a user's action, your page will get reloaded. Therefore, your option would be to use the onbeforeunload event:
<body onbeforeunload="return myFunction()">
http://www.w3schools.com/tags/ev_onbeforeunload.asp
How can i rewrite part of an URL to alter the anchor or has tag to an ampersand? Example:
http://www.test.com/?database=demo#option=set
changed to:
..website../?database=demo&option=set
Notice the change from #option to &option.
I know the # is only processed client side (it never reaches server), so Javascript seemed like the only way to go.
Can Javascript change this on the fly, even without reloading the page? That would eliminate an IF check to find if an instance exists. A reload if the page would work to1...
Thanks for your time and expertise.
"Can Javascript change this on the fly, even without reloading the page?"
No. What you think is a cosmetic change, in reality means totally different resource as represented by URL, because &option would mean new GET parameter.
So page redirect would be needed in order to change this part of URL.
I'm building a little CoffeeScript application with 10 buttons and a container (simple). When the user press on one of the button : the container change.
The buttons look like a navbar and instead of using links (that will reload the entire page), I used javascript (Coffeescript, jquery or whatever) to change the content of the page (with some Ajax query to load data).
The problem is that the back and forward button of the browser can't work with that solution... and I need to find a solution for that. Routing maybe ?
I really like the way Asana.com resolved this issue: actually the address change but the content seems not to be entirely reloaded.
What do you suggest ? Thanks for the help
Hashes. The simplest solution is to define an URL hash every time the user clicks on a button. For example:
location.href = "#" + button.id;
With that, you create a history entry, and the user can press back or forward in the browser.
But how can you check when this happens? There's the hashchange event:
window.onhashchange = function() {
var state = location.hash.substring(1); // chomps the initial #
...
};
Basing your code on the state variable, you can trigger your AJAX calls from there.
By the way, you can change your code altogether, using links instead of buttons with an hash as the href property, which does not reload the page, but creates an history entry and fires the hashchange event.
The hashchange event is supported by every modern browser (that support history.pushState too, a more flexible and powerful way to control your history) and IE8-9.
I'm creating an HTML and Javascript client for running in browser which talks to REST API. I'm using RouteMap to set my URLs. So I've kept a convention something like this
http://mysite.com/#/{ResourceName}/[edit|view|list]/[Id]/
I've set just one route and I'm grabbing these parameters in the function bounded to hashchange. Most of the things work fine. Just two issues and I'm stuck because of them.
If the user clicks on the same link twice, hashchange event doesn't fire. Yes, hash has not changed so obviously it won't fire. But there should be something which can be done and I'm missing that.
If I change something in the UI (like bring up new divs and hide some) for which I don't want to change the hash link, I loose that history and can't go back by clicking the back button properly.
Any help will be grateful.
For #1, you probably want to attach a handler to the link click event. That way you can tell if the link is being clicked. When I use onhashchange, I always attach something to the click event to assist polyfills for onhashchange, so at least I can tell when it's failing.
For #2, I want to point out that having automatic stuff change the user's history is problematic. You could fill someone's history with minute, meaningless hash changes. I recommend only changing the history when the user actually interacts. Short of that, HTML5 does offer pushState and popState. Reference