问题
I'm having problems with history.js, which I don't know how to address.
On the website I'm working on we're using history.js to move between pages - if you click on any link history.js loads URL via AJAX, updates the URL and creates transition effect for content. However, we've got also index page with items; if you click on an item, history.js is not used - the content is loaded via ajax and displayed within the popup. There's also a situation where user can open the URL of the item (for example in new tab, or from search), in that case user should be redirected to the index page with hash of item URL, which will tell JS to run event of clicking on a link that has the hash URL. However, history.js kicks in and redirects to the item URL.
To reiterate:
- user comes to /items/ URL
- left clicks on item (/item-[id]/ URL), which opens content in popup fine (AJAX request)
- right clicks on item and opens the link in new tab
- lands on /item-[id]/ (not AJAX request), and is redirected to /items/#/item-[id]/ via header redirect.
- history.js kicks in as soon as it's loaded and redirects user to /item-[id]/
I'm using HTML5 version of history.js (which I think shouldn't behave like this, dunno though) which redirects as soon as history.js is loaded (no other scripts on the page). Is there any other way to address this issue besides changing the redirect to /items/?/item-[id]/, which (I think) should resolve the issue.
To illustrate the issue:
a.html
<html>
<body>
<script type='text/javascript' src="native.history.js"></script>
<a href="b.html#/b/">b</a>
</body>
</html>
b.html
<html>
<body>
<script type='text/javascript' src="native.history.js"></script>
<a href="a.html#/a/">a</a>
</body>
</html>
Using native.history.js
, which is pure HTML5 version of history.js without any framework bindings found here: https://github.com/browserstate/history.js/blob/master/scripts/bundled-uncompressed/html5/native.history.js
It illustrates the point without any redirects. As soon as you click on any link, you're redirected by history.js to URL after the hash.
回答1:
I've decided to modify history.js directly and add an option preventHashRedirect
-
#1820 // if (currentState ) {
+
#1820 // if (!History.options.preventHashRedirect && currentState ) {
which solves the issue. (basically hash changes are not considered as popstates and don't trigger state changes).
Probably changing isTraditionalAnchor
function (which determines what is considered an anchor and what an URL after the #) to treat all hashes that begin with !
would be a better idea.
-
#1052 // var isTraditional = !(/[\/\?\.]/.test(url_or_hash));
+
#1052 // var isTraditional = /^!/.test(url_or_hash) ? true : !/[\/\?\.]/.test(url_or_hash);
This way you can actually prevent history.js to affect any redirection beginning with !
. (for example if you actually have an anchor with name my.puppy
, doing <a href='#!my.puppy'>
won't cause redirection via history.js.
The below idea of @Martin Barker is still valid, though adding additional redirects strikes me as a little... crude.
回答2:
Removed -- As you just can't use History.js how you want to as you will be changing a core function in the system that would cause untold problems.
your better of making your own as your using jQuery it's quite simple
a.html
<a href="b.html" class="hashlink">B</a>
b.html
<a href="a.html" class="hashlink">A</a>
This will provide the HTML5 .onhashchange event on the window.
// support onhashchange for browsers without support
(function(w, l, u){
'use strict';
if(w.onhashchange == u ){
w.onhashchange = function(curr, old){};
w.oldHash = l.hash.replace("#", "");;
w.onhashchangeCheck = function(){
var hash = l.hash.replace("#", "");
if(hash != w.oldHash){
w.onhashchange(hash, w.oldHash);
w.oldHash = hash;
}
}
setInterval(w.onhashchangeCheck, 100);
}
})(window, document.location);
this shows how you can use onhashchange and to set up any <a></a>
tags with class hashlink
to change the hash instead of redirecting the browser
// handle using hash changes
(function($, w, l, d, u){
'use strict';
w.onhashchange = function(new, old){
// this should handle loading your content via ajax
// on $.ajax().success should handle reading the file into the
// content area of your sight
alert("hash has said you want to load '"+new+"'");
}
$(d).ready(function(){
$('a.hashlink').on('click', function(e){
l.hash = $(this).attr('href');
e.preventDefualt(); // jQuery stop the a link default behavioured of redirecting
//return false; // legacy jQuery support if you need it for the above
});
});
})(jQuery, window, document.location, document);
Please note on the javascript there is a u in the closer function however i don't feed a argument into the function for that variable it this is deliberate to create a ture undefined
result incase some of your code has var undefined = 'something it should not'
来源:https://stackoverflow.com/questions/24757216/history-js-and-header-redirection