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!
Related
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
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 am trying to create a "skip navigation" link without being able to use anchors. The site is built in a peculiar way, where anchor link formatting has been re-purposed. So, I am attempting to allow people to skip the navigation by using focus. However, it isn't working.
HTML code for the skip navigation link itself:
<!-- Start Top Left in Nav Bar -->
<aside>
Skip Navigation
</aside>
<!-- End Top Left in Nav Bar -->
Code to Change the Focus
var nav = document.getElementById('#skipNav');
nav.onclick=skipNav();
function skipNav(){
document.activeElement.blur();
if ($('#linkHome').hasClass('current')==true)
{
$('#homeFocus').focus();
}
if ($('#linkTeam').hasClass('current')==true)
{
$('#teamFocus').focus();
}
if ($('#linkTraining').hasClass('current')==true)
{
$('#trainingFocus').focus();
}
if ($('#linkTesting').hasClass('current')==true)
{
$('#testingFocus').focus();
}
if ($('#linkRemediation').hasClass('current')==true)
{
$('#remediationFocus').focus();
}
if ($('#linkContact').hasClass('current')==true)
{
$('#contactFocus').focus();
}
};
Script to Change Pages and Mark Current Page
var FluidNav = {
init: function() {
$('a[href*="#"]').click(function(e) {
e.preventDefault();
if($(this).attr("href").split("#")[1]) {
FluidNav.goTo($(this).attr("href").split("#")[1]);
}
});
this.goTo("home");
},
goTo: function(page) {
var next_page = $("#"+page);
var nav_item = $('nav ul li a[href=#'+page+']');
$("nav ul li").removeClass("current");
nav_item.parent().addClass("current");
FluidNav.resizePage((next_page.height() + 40), true, function() {
$(".page").removeClass("current"); next_page.addClass("current");
});
$(".page").fadeOut(500);
next_page.fadeIn(500);
document.activeElement.blur();
$('#'+page+'Focus').focus();
FluidNav.centerArrow(nav_item);
},
centerArrow: function(nav_item, animate) {
var left_margin = (nav_item.parent().position().left + nav_item.parent().width()) + 24 - (nav_item.parent().width() / 2);
if(animate != false) {
$("nav .arrow").animate({
left: left_margin - 8
}, 500, function() { $(this).show(); });
} else {
$("nav .arrow").css({ left: left_margin - 8 });
}
},
resizePage: function(size, animate, callback) {
if(size) { var new_size = size; } else { var new_size = $(".page.current").height() + 40; }
if(!callback) { callback = function(){}; }
if(animate) {
$("#pages").animate({ height: new_size }, 400, function() { callback.call(); });
} else {
$("#pages").css({ height: new_size });
}
}
};
$("nav select").change(function() {
if(this.options[this.selectedIndex].value != "#") {
var page = this.options[this.selectedIndex].value.split("#")[1];
FluidNav.goTo(page);
$("html,body").animate({ scrollTop:$('#'+page).offset().top }, 700);
}
});
Any ideas?
Sounds like you're trying to do a 'dynamic skiplink', where you determine the target at runtime?
Skip Navigation
The problem is that when you click a link, navigation happens. A href="" doesn't prevent navigation, it just means that you end up navigating to the current page - and that's going to reset the focus. This happens after your click event handler. So even though you may correctly set the focus where you want to, it ends up being 'lost' when the page reloads.
There's a couple of ways to prevent this: one is to use href="javascript:void(0)" - href specifies where to navigate, and if it evaluates to void, the browser won't navigate at all.
A somewhat cleaner way is to tell the browser not to carry out the default action in the event handler:
function skipNav(e)
{
e.preventDefault(); // prevent default action - link navigation - from taking place
...
--
Couple of other issues with the code:
Don't bother with role="link" on the A - save these attributes for when you are doing something out of the ordinary. The key thing to know is that screenreaders already know how to deal with all the standard HTML elements when they are used in a standard way. So if you are using an as a link, or a as a button, then you don't need to add a role.
But if you are creating a new control of of plain DIVs, or if you are repurposing a HTML element for a different use, then you need a role attribute to tell the screenreader how you are actually using the element.
For example, a DIV that's had an onclick handler and is behaving like a button would need role="button", otherwise a screenreader might ignore it or just say something generic like 'element'. Or if you are creating a button from an A tag, and it ends up behaving like and looking like a button from a user's point of view, then you'd need role="button" so that a screenreader will announce it as a button rather than as a link.
--
Watch for mixing plain DOM vs jQuery conventions - only jQuery uses # to find elements by ID, so use either:
var nav = document.getElementById('skipNav'); // plain DOM way, no #
or
var nav = $('#skipnav'); // jQuery way using selector
--
Watch for functions as values vs calls:
nav.onclick=skipNav();
This will actually call skipNav(), and assign the return value - null! - to onclick. Don't use ()'s when you're setting a callback. You don't need this code anyhow, since you're setting the handler using onClick in the tag anyhow.
Also, note that as your code stands, when skipNav() is called, it tries to call document.activeElement.blur() - but at that point in time - document is still loading - there's no activeElement, so calling blur() on null generates an exception - which you should see in your browser's console/debugging window.
--
Don't use .blur() - there's no need to do this:
document.activeElement.blur();
Instead, just focus the element you want to have focus. The danger with doing .blur() is that if the code after it fails to set the focus somewhere reasonable, focus will end up getting 'lost', which is very inconvenient for a keyboard user, since they have to tab from the start of the page.
--
Javascript coding practice: don't bother with == true in the if() expressions; and unless you expect you expect more than one of the elements to have the 'current' class, use else if instead of plain if: this makes it clear in the code that you're expecting only one branch to be used.
--
Finally, make friends with the browser's debugger (F12 in most): you'll learn some of the above by putting breakpoints in the event handler and your initialization code, and stepping through it to ensure it's behaving as you expect.
I am using sammy javascript framework. Problem is when I click over below anchor browser take me on top of page .... How can I prevent this....
Here is html anchor
Duplicate
and here is JS sammy listner
this.get('#/duplicate/:id', function(context) {
chartName=this.params['id'];
for(i=0;i<chartJSONS.length;i++){
if(chartJSONS[i].chart.renderTo==chartName){
var obj = jQuery.extend(true, {}, chartJSONS[i]);
var dupChart=obj.chart.renderTo+"_duplicate";
obj.chart.renderTo=dupChart;
chartJSONS[chartJSONS.length++]=obj;
}
}
$('#chart').html('');
createCharts();
return false;
});
Any help is highly appreciated...
you need to cancel the navigation after the click event.
because the # navigates your browser to top of the page.
something like:
$('.allDuplicates').click(function(){
return false;
});
or use something else than
<a>
use for example div and you're ok.
You need to do something like this:
$('a').click(function(e){
e.preventDefault();
window.location.hash = $(this).attr('href');
});
I suggest you to add a class to every a element you want to handle like this:
Duplicate
$('.myclass').click(function(e){
e.preventDefault();
window.location.hash = $(this).attr('href');
});
So I've started tackling Javascript and jQuery, and I've put together an event handler for certain link's 'click' events; it takes the href and pulls the content from the appropriate '#container' and loads it into the target container...
<script type="text/javascript">
$(function(){
$('#journeyNav li a').click(cLoad);
});
function cLoad(evt) {
var cLoadURL = $(this).attr('href');
if(!$(this).parent().hasClass('current')) {
$('#stageContentMain').stop().animate({opacity : 0},425, 'easeOutExpo', function(){
$('#stageContentMain').load(cLoadURL + " #stageContent", function() {
$('#stageContentMain').stop().animate({opacity : 1},425, 'easeOutExpo');
});
});
$(this).parent().siblings().removeClass('current');
$(this).parent().addClass('current');
return false;
}
else {
return false;
}
}
</script>
Everything works great actually--especially for my first jQuery function, and second overall Javascript attempt. I am however looking to on Javascript enabled machines (the bookmarking wouldn't be a problem otherwise,) make bookmarking and the 'addthis' social sharing widget to work with the selected content.
Anyone have any ideas or tips?
Checkout the Ben Alman's hashchange event plugin