This was posted as a comment but was later removed, you can try waiting for the window load event:
$(window).on('load hashchange', function(){
$(':target').css('color', 'red');
});
This for me produced mixed results on Chrome, it worked when doing a page refresh (F5) but not when hitting enter in the address bar.
I don't know if there's any way to handle this correctly on page load using the :target
selector but you could always get the hash value and use it as your selector:
$(window).on('load hashchange', function(){
var target = window.location.hash;
$(target).css('color', 'red');
});
UPDATE
I've been doing some research on the issue plus some tests and I have a couple of insights to share:
First off, we need to understand that when calling $(':target')
jQuery internally makes use of querySelectorAll(':target')
which means it's directly related to the CSS specification of the pseudo-class, but why isn't working inside document.ready()
?
Well, I found that wrapping the code inside setTimeout(fn,0)
actually makes the selector available:
$(document).ready(function(){
setTimeout(function(){
$(':target').css('color', 'red'); //THIS WORKS
},0);
});
You can read this answer for an explanation on how adding a zero-ms timeout actually makes a difference, but basically it allows the browser to complete other non-javascript related tasks (in which we would find making the actual CSS pseudo-class available for query). I believe Firefox somehow manages its internal processes differently and that's why the code works there without the need for a timeout.
Now I also discovered that jQuery's internal sizzle selector engine provides a fallback for browsers that do not support CSS :target
pseudo-class, which you can use inside document.ready()
without issue:
$(document).ready(function(){
$(':target()').css('color', 'red');
});
This works because instead of relying on the CSS class it is a javascript implementation that makes use of the hash property on the window.location object, internally it is defined as follows:
"target": function( elem ) {
var hash = window.location && window.location.hash;
return hash && hash.slice( 1 ) === elem.id;
}
The only think you should note is that this function will go through every element on the page if it's not passed a selector like :target(div)
, so I believe using the workaround I provided earlier would still be a better option than this.