I have a strange problem with bootstrap and jquery javascript.
I am using the following jquery script to get smooth scrolling when clicking on a anchor and when returning to the top of page whith the back button of browser (with removing #anchorName extension) :
$(function() {
$('a[href*=#]:not([href=#])').click(function(event) {
event.preventDefault();
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
var hash = this.hash; // 'this' will not be in scope in callback
$('html,body').animate({ scrollTop: target.offset().top - 55}, 300, function() {
href = window.location.href;
history.pushState({page:href}, null, href.split('#')[0]+hash);
});
return false;
}
}
});
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
var target = window.location.href.split('#');
var href = target[0];
if (state) {
$('html,body').animate({ scrollTop: 0 }, 300, function() {
history.replaceState({}, null, href);
})
}
});
window.onload = function() {
history.replaceState({ path: window.location.href }, '');
}
});
If I use double quote ( $('a[href*="#"]:not([href="#"])') ) this script above works well but the page that I have tested contains a HTML5 canvas and this canvas doesn't display.
On the other side, If I don't use double quote ( $('a[href*=#]:not([href=#])') )), the "anchor" functionalities don't work (I have not a smooth scrolling) and the HTML5 canvas is displayed ;
I saw on forums that solution may be :
1) double quoting :
$('a[href*="#"]:not([href="#"])')
OR
2) Unescape # character
$('a[href*=\\#]:not([href=\\#])')
I tried these 2 solutions but none of them works.
with jquery 1.12.0, I get the following error :
Error: Syntax error, unrecognized expression: a[href*=#]:not([href=#])
Any help is welcome
UPDATE SOLUTION :
Initially, my code was :
$(function() {
$('a[href*=#]:not([href=#])').click(function(event) {
event.preventDefault();
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
var hash = this.hash; // 'this' will not be in scope in callback
$('html,body').animate({ scrollTop: target.offset().top - 55}, 300, function() {
href = window.location.href;
history.pushState({page:href}, null, href.split('#')[0]+hash);
});
return false;
}
}
});
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
var target = window.location.href.split('#');
var href = target[0];
if (state) {
$('html,body').animate({ scrollTop: 0 }, 300, function() {
history.replaceState({}, null, href);
})
}
});
window.onload = function() {
history.replaceState({ path: window.location.href }, '');
}
});
Finally, the version below works :
$(window).bind("load", function () {
$('a[href*="#"]:not([href="#"])').click(function(event) {
event.preventDefault();
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
var hash = this.hash; // 'this' will not be in scope in callback
$('html,body').animate({ scrollTop: target.offset().top - 55}, 300, function() {
href = window.location.href;
history.pushState({page:href}, null, href.split('#')[0]+hash);
});
return false;
}
}
});
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
var target = window.location.href.split('#');
var href = target[0];
if (state) {
$('html,body').animate({ scrollTop: 0 }, 300, function() {
history.replaceState({}, null, href);
});
}
});
});
It seems that, for initial version, the script was executed before the page was loading, maybe the canvas was not loading too. By put all the script into "$(window).bind("load", , I think that going to anchor and return to top of page are executed once all is loaded. Anyone could confirm this ?
Thanks