Making hash crawlable with #! and surviving the change - javascript

I'm trying to make my site crawlable by changing the # to #!. The page works OK when clicking on the link, but I cannot manage to fix the script for calling the hash directly from the URL.
This is what I have
HEAD
$(function() {
$("#tabs a").click(function() {
var page = this.hash.substr(2);
$.get(page+".php", function(gotHtml) {
$("#content").html(gotHtml)
});
});
(location.hash) ? $("a[href="+location.hash+"]").click() : $("#tabs a:first").click()
});
BODY
< ul id="tabs">
< li>< a href="#!foo" >foo</a>< /li>
< li>< a href="#!foo2" >foo2</a>< /li>
< li>< a href="#!foo3" >foo3</a>< /li>
< /ul>
When I click on foo, content loads ok, but if I call my site with www.foo.com/#!foo, it doesn't load the content.
Can anyone guide me?

If you look in your error console you'll see that it's throwing the following exception:
Uncaught Error: Syntax error, unrecognized expression: [href=#!foo2]
In order to fix this, you can change your JavaScript ever so slightly.
$(function() {
$("#tabs a").click(function() {
var page = this.hash.substr(2);
$.get(page+".php", function(gotHtml) {
$("#content").html(gotHtml)
});
});
(location.hash) ? $("a[href='"+location.hash+"']").click() : $("#tabs a:first").click()
});
Notice I just stuck single quotes around your href portion of your selector.
On a related note, I would recommend that if you're going to do hash-bangs (they are a headache) that you make the href attribute the actual URL value that you're going to. In the JavaScript do the switch over to a hash-bang. The reason for this is that users with JavaScript disabled will not be able to use your site. Your click function will change ever so slightly to set the hash, load the page, and disable the default click behavior.
Update for question: On the related note, I meant if the href="#!foo" change that href to actually be href="foo.php". If a user does not have JavaScript enabled they can go to foo.php and see the page. If the user does have JavaScript place the hashbang in the URL and do what you did previously. You can do this manually; however, libraries like jQuery BBQ can really make this trivial.

Related

jquery go to anchor on page load

i have a WordPress site and problems with anchors. i have a page with several anchors which are linked to in the main menu. when i am on the page itself, all anchors work fine, but if I'am on any other page, they don't work, at least not in all browsers and the anchors are ignored.
As being informed it is a chrome bug, ive found this solution:
<script type="text/javascript">
jQuery(window).load(function(){
var hashNum = 0;
if (window.location.hash != ''){
hashNum = window.location.hash.replace("#oneofmanyanchors", "");
console.log('hashNum: ' + hashNum);
};
hashMenu = jQuery('[data-q_id="#oneofmanyanchors"]').offset().top;
jQuery('html,body').animate({
scrollTop: hashMenu
}, 0);
});
</script>
above code is working and fixes the issues i had in chrome and ff.
however i need this added functionality: At the moment it is addressing only one specific anchor, but i need it to work with any anchors in the page url, not just the one above (anchors are referenced with the data-q_id attribute).
so the code needs to be updated that it grabs any given anchor from the page URL and go to / scroll to that anchor (once) via jquery after first page load.
How do i achieve this?
Thanks in advance!
PS: The problem is caused by theme incompatibility with a certain plugin i need...
I think this should work in every browser - what happens to be the problem?
In order to achieve this in jquery you should scroll to the element/anchor with javascript as soon as the document is loaded.
So like this:
$(function() {
location.hash = "#" + hash;
});
I still think you should find out what went wrong and why the linken from another page doesn't work in some browser before using a workaround for the problem. Your code will just ged more and more messy like that.
How to scroll HTML page to given anchor using jQuery or Javascript?
and here
$(document).ready shorthand

Hash link disables relative link in HTML

I'm building a webapp that basically its an one-page webapp so to link to another part of the app is like this:
This is possible because I used JavaScript that contains animations and different stuff, the problem is that somehow, this method disables the possibility to link like this:
How can I have both links, without disabling the hash links?
EDIT: To be honest I dont know which part of the js its causing this behaviour because I took a template, but here is the js:
https://github.com/gomobile/template-list-view/blob/master/www/lib/appframework/appframework.ui.min.js
I believe you have a code like this
$('a').on('click', function(e) {
e.preventDefault();
});
You need to have an if like
if ($(this).attr('href').indexOf('#') == 0) {
e.preventDefault();
}
OR better change the selector to:
$("a[href^=#]").on('click', function(e) {
e.preventDefault();
// your animation here.
});
This code will just apply to anchor elements that have the href starting with #
------- update --------
You added a minified js :).
If you don't have the problem in your code, you can fix it with a hack like this:
$('a:not([href^=#])').on('click', function(e) {
window.location.href = $(this).attr('href');
});
But you should really find the issue, not fix it like this :)

Ajax inserted content not accessible in DOM

I am working on a pure jquery/js site, mostly to practice some jquery. I am using a load statement to load a menu from a file of common html, like so:
$('#categoryListing').load('../common.html #categoryLinksUL');
which loads:
<ul id="categoryLinksUL">
<li>Anklets</li>
<li>Bracelets</li>
</ul>
The problem is where I am using it now I need to alter the href of the above links, but they are not part of the dom. In previous instances I was able to use .live(click... But not here. Is there a way I can accomplish this?
Specifically I need to load the links and change the href from #anklets to ?category=anklets
What about the following?
$('#categoryListing').load('../common.html #categoryLinksUL', function() {
$('li a[href^="#"']').each(function () {
this.href = '?category=' + this.href.substr(1);
});
});
In my example, after the load is completed, the anonymous function is called. It takes every anchor with a hash HREF and replaces it with an HREF based on your description.
Thank you Dimitry, you solution basically worked. I finally used:
$('#categoryListing').load('../common.html #categoryLinksUL', function() {
$('#categoryListing li a').each(function () {
var hashPos=this.href.indexOf("#");
var tCategory = this.href.substr(hashPos+1,this.href.length );
});
});
So why did jQuery recognize categoryListing there? I tried moving the each function outside of the load function and categoryListing did not contain any links. Is it because maybe the load was not completed when it tried to get categoryListing links? Seems like that is possible.
Thanks,
Todd

jQuery - Could use a little help with a content loader

I'm not very elite when it comes to JavaScript, especially the syntax. So I'm trying to learn. And in this process I'm trying to implement a content loader that basically removes all content from a div and inserts content from another div from a different document.
I've tried to do this on this site:
www.matkalenderen.no - Check the butt ugly link there. See what happens?
I've taken the example from this site:
http://nettuts.s3.cdn.plus.org/011_jQuerySite/sample/index.html#index
But I'm not sure this example actually works the way I think it does. I mean, if the code just wipes out existing content from a div and inserts content from another div, why does the other webpages in this example include doctype and heading etc etc? Wouldn't you just need the div and it's content? Without all the other stuff "around"? Maybe I don't get how this works though. Thought it worked mosly like include really.
This is my code however:
$(document).ready(function() {
var hash = window.location.hash.substr(1);
var href = $('#dynloader a').each(function(){
var href = $(this).attr('href');
if(hash==href.substr(0,href.length-5)){
var toLoad = hash+'.html #container';
$('#container').load(toLoad)
}
});
$('#dynloader a').click(function(){
var toLoad = $(this).attr('href')+' #container';
$('#container').hide('fast',loadcontainer);
$('#load').remove();
$('#wrapper').append('<span id="load">LOADING...</span>');
$('#load').fadeIn('normal');
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
function loadcontainer() {
$('#container').load(toLoad,'',showNewcontainer())
}
function showNewcontainer() {
$('#container').show('normal',hideLoader());
}
function hideLoader() {
$('#load').fadeOut('normal');
}
return false;
});
});
The jQuery .load() has some extra functionality in it to support this.
You can see it in the docs here (look at `Loading Page Fragments')
In your example here's the important part: hash+'.html #container' the space before the #container means that jQuery will grab that URL, look for the element with id="container" and fetch only that element's content's discarding the rest of the page. This lets .load() work in a more generic way without what you're fetching being specifically designed for only ajax loading.
In your case I think you just need to remove #content from the end unless you're looking for that element. It's not saying "look for content" that's just the ID they used for the element they wanted to look for. It could have been #divToLoad which would be a clearer example IMO.

Why must I define a variable outside a javascript function definition? (jQuery / #anchor question)

I am writing a jQuery function that relies on knowing the current #anchor of the page. I am using the jQuery URL Parser plugin to get the anchor.
$.fn.vtabs = function() {
alert("Your anchor is "+$.url.attr('anchor'));
}
This code gives me the anchor "#nav" endlessly (I use #nav in some of the my links). I can type in "#newanchor" into the browser bar endless times, and click url's to this page that use different anchors, but always this code gives me "#nav".
I fixed my problem by changing the code to:
var current_anchor = $.url.attr('anchor');
$.fn.vtabs = function() {
alert("Your anchor is "+current_anchor);
}
Now it always gives me the correct anchor. But I don't know why, and it appears messy to have that variable defined outside of the function.
Looks like there might be some caching going on with that plugin. Why not skip the plugin and just use window.location.hash to get the anchor?

Categories