I saw something really different, and I have no idea how to do it.
The site Rdio.com when you click in any link, the url change totally (not #).
But the div in the bottom of the page (that is playing the song) do not reload.
How they do this?
you can do this with an ajax load and then you mainipulate the browser history.
like so:
/*clickhandler Hauptmenü*/
$('#main-nav a').on('click', function(e){
var href = $(this).attr('href'),
title = $(this).text();
loadContent(href,title);
/*manipulate Browser history */
history.pushState({path: href, titel: title}, $(this).attr('href'), 'http://www.example.com/'+$(this).attr('href'));
e.preventDefault();
});
window.addEventListener('popstate', function(e){
loadContent(e.state.path, e.state.titel);
}, false);
function loadContent(href,title){
var href = href,
container = $('#main-cont');
container.fadeOut(100, function(){
container.load( href +' #main-cont', function(){
container.fadeIn(200);
$('title').replaceWith('<title>' + title + '</title>');
});
});
};
I hope this answers your question.
This is done with JavaScript's new history object, using the pushState and popState methods. See also http://diveintohtml5.info/history.html
Correct me if I'm wrong - considering that I havent been to their site - but I believe that they would be using an Iframe of some sorts - considering that they would have to reload that div if they did otherwise
Related
I am a bit confused, because I just want to add a hash to an existing url via varibale and open it via a href.
Example:
$( ".MyLink" ).each( function(){
var href = $(this).attr('href');
$(this).attr("href", "https://website.com/subpage#" + href);
});
Result (browser url) after clicking on this link:
https://website.com/subpage/#test
If I am right, a correct hash link should look like this ...
https://website.com/subpage#test
... without the "/" after subpage.
So, I am correct or it doesn't matter? If yes, how can I change it?
I also realized that my browser(s) change my url from https://website.com/subpage#test to https://website.com/subpage/#test if I just add it in the browser bar and press enter. Is that new?
Maybe it is important to know that I use wordpress?
OK, it seemes to be a php/browser/wordpress rule that # become /#, because this script creates an endless refresh-loop for me:
var urlupdate = window.location.href.replace("/#", "#");
window.location.href = urlupdate;
Update: As described in this answer, it shouldn't make a difference if your Javascript was written properly, it seems to be even considered as a best practice. If you want to get rid of it anyways you may want to check your wordpress settings, maybe the second answer of the given question may give you a hint!
In case that the trailing slash comes from the a tag, you could check whether the string in the href attribute starts with a slash and remove it then:
$( ".MyLink" ).each( function(){
var href = $(this).attr('href');
if (href.charAt(0) === '/') {
href = href.substring(1, href.length);
}
$(this).attr("href", "https://website.com/subpage#" + href);
});
I have a dynamicpage.js script below:
$(function() {
var newHash = "",
$mainContent = $("#main-content"),
$pageWrap = $("#page-wrap"),
baseHeight = 0,
$el;
$pageWrap.height($pageWrap.height());
baseHeight = $pageWrap.height() - $mainContent.height();
$("nav").delegate("a", "click", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).bind('hashchange', function(){
newHash = window.location.hash.substring(1);
if (newHash) {
$mainContent
.find("#guts")
.fadeOut(200, function() {
$mainContent.hide().load(newHash + " #guts", function() {
$mainContent.fadeIn(200, function() {
$pageWrap.animate({
height: baseHeight + $mainContent.height() + "px"
});
});
$("nav a").removeClass("current");
$("nav a[href="+newHash+"]").addClass("current");
});
});
};
});
$(window).trigger('hashchange');
});
What that code does is it makes a link turn from href="/staff" to href="/#/staff" for the dynamic loading but it only changes the link if the <a> tag is wrapped in a <nav> tag so
it only works if its <nav>staff</nav>
I tried to make it ("#dynamic") in the jquery/js and added id="dynamic" to the <a> tag but it did not work.
How would I make it so I can just add id="dynamic" to the <a> tag instead of wrapping <nav> around EACH link i want to use this.
I would use event delegation instead ..
It can be attached to the document to be triggered wherever the link is located in the DOM ( and because click event is not a flooding one like mosemove)
Then simply add the 'dynamic' class to those links concerned by this behaviour
$(document).on('click', function(e){
var $t = $(e.target),
$a = $t.closest('a.dynamic');
if( $a.length ){
window.location.hash = $a.attr('href');
return false;
}
});
If I understand you correctly, though I'm not sure I do...
Just adding in an ID to a link won't do what you want, because an ID by itself doesn't mean anything to a web browser. It's the web browser that's responsible for doing Stuff when a user follows a link, which by default would be to follow that link and load a page; you're modifying the link address so that the interesting stuff is actually held in a named anchor (hence the "#") then relying on a JavaScript event listener to catch the "click" event and do something novel.
http://www.w3.org/TR/html401/struct/links.html#h-12.2.1
There's no way around the need to attach this listener to every link that needs the special treatment.
By making sure you generate HTML such that the "interesting" links have a specific common named class though, you can at least use the jQuery equivalent of document.getElementsByClassName, which ought to be simpler and faster than using a CSS selector based approach as in your example code.
http://api.jquery.com/class-selector/
You will still have to iterate over this and add listeners. Is it really worth all this JavaScript, CPU overhead and browser incompatibility risks (especially on mobile) just to override the behaviour of a link that browsers already deal with pretty adequately? All that history patching you have to do as well (whether or not it's hidden by a framework)? Just to avoid a page refresh? Personally, I'm really not sure it is!
I want to do the inverse of what I've been finding so far. I'm setting a lot of heights with js and I want to navigate to the hashtag in the url after the page has loaded. I'm guessing this is simple but I'm not seeing the obvious answer... for an example, check here...
http://alavita.rizenclients.com/#story
Attempted this using the code...
$(window).load(function() {
var hashTag = window.location.hash;
window.location = '/' + hashTag;
});
doesn't actually take me to the top of the tagged section...
If you simply want to change the hash after page loads:
window.onload = function (event) {
window.location.hash = "#my-new-hash";
};
If you want to navigate to the URL with new hash:
window.location.href = "http://website.com/#my-new-hash";
If you want to listen for changes in the hash of the URL; you can consider using the window.onhashchange DOM event.
window.onhashchange = function () {
if (location.hash === "#expected-hash") {
doSomething();
}
};
But it is not supported by every major browser yet. It now has a wide browser support. You can also check for changes by polling the window.location.hash on small intervals, but this is not very efficient either.
For a cross-browser solution; I would suggest Ben Alman's jQuery hashchange plugin that combines these methods and a few others with a fallback mechanism.
EDIT: After your question update, I understand you want the page to scroll to a bookmark?:
You can use Element.scrollTop or jQuery's $.scrollTop() method.
$(document).ready(function (event) {
var yOffset = $("#my-element").offset().top;
$("body").scrollTop(yOffset);
});
See documentation here.
For some reason both MS Edge 42 and IE 11 will not scroll to the new bookmark for me, even when doing a window.location.reload(true) after setting the new bookmark. So I came up with this solution: insert this script on the page you're loading (requires jquery)
$(document).ready(function() {
var hash = window.location.hash;
if (hash) {
var elem = document.getElementById(hash.substring(1));
if (elem) {
elem.scrollIntoView();
}
}
});
Using scrollTo or scrollIntoView will not respect any offset created by the :target css selector, which is often used to make the page scroll to just above the anchor, by setting it to position: relative with a negative top.
This will scroll to the anchor while respecting the :target selector:
if (location.hash) {
window.location.replace(location.hash);
}
You could just set the current location:
window.location = 'http://alavita.rizenclients.com/#story';
Or set the hash (if it isn't already), then reload:
window.location.hash = hashTag;
window.location=window.location.href;
You changed your question.
Check out this solution. https://stackoverflow.com/a/2162174/973860 so you understand what is going on and how to implement a cross browser solution.
NOTICE: At the bottom he mentions a jquery plugin that will do what you need.
http://benalman.com/projects/jquery-hashchange-plugin/
This plugin will allow you to do something like this. This will work for your current page. But you may want to modify it to be more robust.
$(function(){
// Bind the event.
$(window).hashchange( function(){
// get the hash
var hash = window.location.hash;
// click for your animation
$('a[href=' + hash + ']').click();
})
// Trigger the event (useful on page load).
$(window).hashchange();
});
I have a sliding panel set up on my website.
When it finished animating, I set the hash like so
function() {
window.location.hash = id;
}
(this is a callback, and the id is assigned earlier).
This works good, to allow the user to bookmark the panel, and also for the non JavaScript version to work.
However, when I update the hash, the browser jumps to the location. I guess this is expected behaviour.
My question is: how can I prevent this? I.e. how can I change the window's hash, but not have the browser scroll to the element if the hash exists? Some sort of event.preventDefault() sort of thing?
I'm using jQuery 1.4 and the scrollTo plugin.
Many thanks!
Update
Here is the code that changes the panel.
$('#something a').click(function(event) {
event.preventDefault();
var link = $(this);
var id = link[0].hash;
$('#slider').scrollTo(id, 800, {
onAfter: function() {
link.parents('li').siblings().removeClass('active');
link.parent().addClass('active');
window.location.hash = id;
}
});
});
There is a workaround by using the history API on modern browsers with fallback on old ones:
if(history.pushState) {
history.pushState(null, null, '#myhash');
}
else {
location.hash = '#myhash';
}
Credit goes to Lea Verou
The problem is you are setting the window.location.hash to an element's ID attribute. It is the expected behavior for the browser to jump to that element, regardless of whether you "preventDefault()" or not.
One way to get around this is to prefix the hash with an arbitrary value like so:
window.location.hash = 'panel-' + id.replace('#', '');
Then, all you need to do is to check for the prefixed hash on page load. As an added bonus, you can even smooth scroll to it since you are now in control of the hash value...
$(function(){
var h = window.location.hash.replace('panel-', '');
if (h) {
$('#slider').scrollTo(h, 800);
}
});
If you need this to work at all times (and not just on the initial page load), you can use a function to monitor changes to the hash value and jump to the correct element on-the-fly:
var foundHash;
setInterval(function() {
var h = window.location.hash.replace('panel-', '');
if (h && h !== foundHash) {
$('#slider').scrollTo(h, 800);
foundHash = h;
}
}, 100);
Cheap and nasty solution.. Use the ugly #! style.
To set it:
window.location.hash = '#!' + id;
To read it:
id = window.location.hash.replace(/^#!/, '');
Since it doesn't match and anchor or id in the page, it won't jump.
Why dont you get the current scroll position, put it in a variable then assign the hash and put the page scroll back to where it was:
var yScroll=document.body.scrollTop;
window.location.hash = id;
document.body.scrollTop=yScroll;
this should work
I used a combination of Attila Fulop (Lea Verou) solution for modern browsers and Gavin Brock solution for old browsers as follows:
if (history.pushState) {
// IE10, Firefox, Chrome, etc.
window.history.pushState(null, null, '#' + id);
} else {
// IE9, IE8, etc
window.location.hash = '#!' + id;
}
As observed by Gavin Brock, to capture the id back you will have to treat the string (which in this case can have or not the "!") as follows:
id = window.location.hash.replace(/^#!?/, '');
Before that, I tried a solution similar to the one proposed by user706270, but it did not work well with Internet Explorer: as its Javascript engine is not very fast, you can notice the scroll increase and decrease, which produces a nasty visual effect.
This solution worked for me.
The problem with setting location.hash is that the page will jump to that id if it's found on the page.
The problem with window.history.pushState is that it adds an entry to the history for each tab the user clicks. Then when the user clicks the back button, they go to the previous tab. (this may or may not be what you want. it was not what I wanted).
For me, replaceState was the better option in that it only replaces the current history, so when the user clicks the back button, they go to the previous page.
$('#tab-selector').tabs({
activate: function(e, ui) {
window.history.replaceState(null, null, ui.newPanel.selector);
}
});
Check out the History API docs on MDN.
This solution worked for me
// store the currently selected tab in the hash value
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');
And my full js code is
$('#myTab a').click(function(e) {
e.preventDefault();
$(this).tab('show');
});
// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function(e) {
var id = $(e.target).attr("href").substr(1);
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// window.location.hash = '#!' + id;
});
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
// console.log(hash);
$('#myTab a[href="' + hash + '"]').tab('show');
I'm not sure if you can alter the original element but how about switch from using the id attr to something else like data-id? Then just read the value of data-id for your hash value and it won't jump.
When using laravel framework, I had some issues with using a route->back() function since it erased my hash. In order to keep my hash, I created a simple function:
$(function() {
if (localStorage.getItem("hash") ){
location.hash = localStorage.getItem("hash");
}
});
and I set it in my other JS function like this:
localStorage.setItem("hash", myvalue);
You can name your local storage values any way you like; mine named hash.
Therefore, if the hash is set on PAGE1 and then you navigate to PAGE2; the hash will be recreated on PAGE1 when you click Back on PAGE2.
Is there an easy way to have JavaScript mimic a User clicking an anchor tag on a page? That means the Referrer Url needs to be set. Just setting the document.location.href doesn't set the Referrer Url.
<script>
$(document).ready(function () {
$("a").click();
});
</script>
Go here
This doesn't work because there isn't a Click() event setup for the link.
You could do:
window.location = $("a").attr("href");
If you want to keep the referrer, you could do this:
var href = $('a').attr('href');
$('<form>').attr({action: href, method: 'GET'}).appendTo($('body')).submit();
It is hackish, but works in all browsers.
document.location.href = "#wanted_Location";
Maybe something like this is what you're looking for?
$(document).ready(function () {
$("a").each(function(){
if($(this).click()){
document.location.href = $(this).attr("href");
}
});
});
There is a simpler way to achieve it,
HTML
Bootstrap is life
JavaScript
// Simulating click after 3 seconds
setTimeout(function(){
document.getElementById('fooLinkID').click();
}, 3 * 1000);
Using plain javascript to simulate a click.
You can check working example here on jsFiddle.
Okay, referer doesn't get set using document.location (as per my other answer), might work with window.navigate(url)? If that doesn't work the following might, though it's quite - ehrm - ugly:
$(function() {
$("a").each(function(){
if($(this).click()){
$('<form method="get" action="' + $(this).attr("href") + '"></form>').appendTo("body").submit();
return false;
}
});
});