when I click on navbar item the hash link scroll event not matched with the correct nav menu item
I tried to change the 'scrollto' variable up or down but the problem still exists
below is the code :
// Smooth scroll for the menu and links with .scrollto classes
var scrolltoOffset = $('#header').outerHeight() - 21;
var clicked = false;
$('.nav-menu a, #mobile-nav a, .scrollto').on('click', function(e) {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
debugger;
if (target.length) {
e.preventDefault();
var scrollto = target.offset().top - scrolltoOffset;
if ($(this).attr("href") == '#header') {
scrollto = 0;
}
$('html, body').animate({
scrollTop: scrollto
}, 1500, 'easeInOutExpo');
if ($(this).parents('.nav-menu').length) {
$('.nav-menu .menu-active').removeClass('menu-active');
$(this).closest('li').addClass('menu-active');
}
if ($('body').hasClass('mobile-nav-active')) {
$('body').removeClass('mobile-nav-active');
$('#mobile-nav-toggle i').toggleClass('fa-times fa-bars');
$('#mobile-body-overly').fadeOut();
}
return false;
}
}
});
this is the live site innovators.com
Easy fix. You are not scrolling enough.
Just scroll two pixels less: -21 => -23
// Smooth scroll for the menu and links with .scrollto classes
var scrolltoOffset = $('#header').outerHeight() - 23;
var clicked = false;
$('.nav-menu a, #mobile-nav a, .scrollto').on('click', function(e) {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
debugger;
if (target.length) {
e.preventDefault();
var scrollto = target.offset().top - scrolltoOffset;
if ($(this).attr("href") == '#header') {
scrollto = 0;
}
$('html, body').animate({
scrollTop: scrollto
}, 1500, 'easeInOutExpo');
if ($(this).parents('.nav-menu').length) {
$('.nav-menu .menu-active').removeClass('menu-active');
$(this).closest('li').addClass('menu-active');
}
if ($('body').hasClass('mobile-nav-active')) {
$('body').removeClass('mobile-nav-active');
$('#mobile-nav-toggle i').toggleClass('fa-times fa-bars');
$('#mobile-body-overly').fadeOut();
}
return false;
}
}
});
Related
I'm trying to make a module called ScrollToAnchor that has a function called goToTarget that I will be able to call like ScrollToAnchor.goToTarget(target);
However it says that
ScrollToAnchor.goToTarget is not a function
I think ScrollToAnchor is of type jQuery how I have it because of the $. Here is the code:
var ScrollToAnchor = $(function() {
var headerHeight = 70;
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
if (goToTarget(this.hash))
return false;
}
});
/*$('input[data-target]').click(function() {
if (gotoTarget($(this).data("target")))
return false;
})*/
var goToTarget = function(targetName) {
var target = $(targetName);
target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top - headerHeight
}, 1000);
return true;
}
return false;
}
return {
goToTarget: goToTarget
}
});
What am I doing wrong? If i remove the $ from var ScrollToAnchor = $(function () { then the jQuery inside ScrollToAnchor doesn't work.
But if I leave the $ there then it thinks ScrollToAnchor is type jQuery and ScrollToAnchor.goToTarget is not a function.
The $(function() {...}) is a short hand of $( document ).ready( handler ).
So the result of $(function() {...}) is a jQuery result set containing the document as element.
You are looking for event delegation:
$(document).on('click', 'a[href*="#"]:not([href="#"])', function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
if (goToTarget(this.hash))
return false;
}
});
This will ensure that the click event will be use for all a element no matter when they have been added to the DOM and allows your to make your goToTarget available in the global scope in an easy way. Your final code will then look this way:
var ScrollToAnchor = (function() {
var headerHeight = 70;
// event handler with delegation
$(document).on('click', 'a[href*="#"]:not([href="#"])', function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
if (goToTarget(this.hash))
return false;
}
});
function goToTarget(targetName) {
var target = $(targetName);
target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top - headerHeight
}, 1000);
return true;
}
return false;
}
return {
goToTarget: goToTarget
}
}());
Using event delegation there is no need to wrap you whole code into a $(function() {...}) and your ScrollToAnchor is public available.
Turn ScrollToAnchor into a normal function. This function will be in the global scope:
window.ScrollToAnchorFactory = function () {
var headerHeight = 70;
$('a[href*="#"]:not([href="#"])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
if (goToTarget(this.hash))
return false;
}
});
/*$('input[data-target]').click(function() {
if (gotoTarget($(this).data("target")))
return false;
})*/
var goToTarget = function (targetName) {
var target = $(targetName);
target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top - headerHeight
}, 1000);
return true;
}
return false;
}
return {
goToTarget: goToTarget
}
};
You could also use a module.export instead of putting this in the global scope, if you'd like to create a commonJS module out of this code. That would allow you to require() it into other files (using Browserify to compile).
If you do decide to just keep ScrollToAnchorFactory in the global scope, wherever you need to use scrollToAnchor.goToTarget (in the same file or a different one)...
$(function() {
var scrollToAnchor = window.ScrollToAnchorFactory();
// you can now use scrollToAnchor.goToTarget(target)
});
You'll want jQuery's DOM ready function wrapped around this part, so that ScrollToAnchorFactory doesn't try to init before your anchors are fully formed in the DOM.
I need something link this
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
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) {
$('html,body').animate({
scrollTop: target.offset().top-55
}, 1000);
return false;
}
}
});
});
But it works only for that link offer. I want that this code works for this link for example offer2
I think your jquery selector is wrong.
See
http://jsfiddle.net/9shvmhwh/5/
$(function() {
$("a[href*='#']:not([href='#'])").click(function(event) {
location = $(this).attr('href');
event.stopPropgation();
return true;
});
});
How can I add a 3 seconds pause before the smooth scroll?
The user will click on the button, then there will be a sleep of 3 seconds and then the smooth scroll will run.
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
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) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
You could add an setTimeout() like so:
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
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) {
setTimeout(function(){
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
}, 3000);
return false;
}
}
});
});
You could use the JavaScript-standard setTimeout() function:
JavaScript
setTimeout(function () {
// function that is executed after the timer ends
}, 3000);
As you can see, the setTimeout function takes two parameters: a handler (function) that will be executed after the timer ends, and an integer, that defines the timer duration in milliseconds.
If you are unfamiliar with all this "handling" concept, consider the below example instead, where we do the same, but first "save" the function in a variable:
JavaScript
var fnCallback = function () {
console.log('This plague works.');
};
// Call setTimeout() with a handler function (fnCallback), and an integer (3000)
setTimeout(fnCallback, 3000);
I'm using a smooth scroll script for a site I'm currently working on, and I've got a really annoying problem what I've experienced before with the same script. It works nice and smoothly but when I click on one of the navigation points what should lead me to the div(or a) I'm trying to target, it shows me the targeting area for like 0.1 seconds, and then it starts to scroll. It doesn't happen everytime, but often enough to be annoying. How could I prevent this? Here is the script I'm talking about:
$(window).load(function(){
$(".contactLink").click(function(){
if ($("#contactForm").is(":hidden")){
$("#contactForm").slideDown("slow");
}
else{
$("#contactForm").slideUp("slow");
}
});
});
function closeForm(){
$("#messageSent").show("slow");
setTimeout('$("#messageSent").hide();$("#contactForm").slideUp("slow")', 2000);
}
$(window).load(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
$('a[href*=#]').each(function() {
if ( filterPath(location.pathname) == filterPath(this.pathname)
&& location.hostname == this.hostname
&& this.hash.replace(/#/,'') ) {
var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : true;
if ($target) {
var targetOffset = $target.offset().top - 110;
$(this).click(function() {
$('html, body').animate({scrollTop: targetOffset}, 1400);
var d = document.createElement("div");
d.style.height = "101%";
d.style.overflow = "hidden";
document.body.appendChild(d);
window.scrollTo(0,scrollToM);
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
return false;
});
}
}
});
});
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
return false;
});
move the return false out of the setTimeOut
Found the solution:
$(this).click(function(e) {
e.preventDefault();
Now it rolls fine.
could some one please integrate my code with keyboard arrows to navigate the menu up and down with less code as possible. i've tried some plugins and searched alot but my little experience does not help me!
$(function() {
$('ul.nav a').each(function(i, elem) {
$(elem).bind('click', function(event) {
event.preventDefault();
var offset = i * 38;
$('ul.nav').stop().animate({backgroundPosition: '0 ' + offset + 'px'}, 2000,'easeOutQuart');
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 2000,'easeOutQuart');
$('ul.nav a').css({'cursor': 'pointer', 'color': '#643D21'});
$anchor.css({'cursor': 'default', 'color': '#995D32'});
event.preventDefault();
});
});
});
HTML code
<ul class="nav">
<li>what</li>
<li>who</li>
<li>portfolio</li>
<li>contact</li>
appreciated,
UPDATE: Why don't I just give you the whole thing? http://jsfiddle.net/MwMt3/2
$(function() {
var hgt = $('ul li:first').height();
$('ul.nav a').each(function(i, elem) {
$(elem).bind('click', function(event) {
event.preventDefault();
var offset = i * hgt;
animate_bg(offset);
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 800);
$('ul.nav a').css({
'cursor': 'pointer',
'color': '#643D21'
});
$anchor.css({
'cursor': 'default',
'color': '#995D32'
});
event.preventDefault();
});
});
$(document).keydown(function(e) {
var bgtop = parseInt($('ul.nav').css("backgroundPosition").split(" ")[1], 10);
var sel = Math.ceil(bgtop / hgt);
if (e.keyCode == 39 || e.keyCode == 40) { // right, down
if (sel < 0) {
animate_bg(0);
} else if (sel < $('ul.nav li').length - 1) {
var offset = (sel + 1) * hgt;
animate_bg(offset);
}
} else if (e.keyCode == 37 || e.keyCode == 38) { // left, up
if (sel < 0) {
var maxoffset = $('ul.nav li').length * hgt;
animate_bg(maxoffset);
} else if (sel > 0) {
var offset = (sel - 1) * hgt;
animate_bg(offset);
}
}
});
});
function animate_bg(offset) {
$('ul.nav').stop().animate({
backgroundPosition: '0 ' + offset + 'px'
}, 800);
}
It would help if you could describe a bit more clearly what you mean by "navigate the menu up and down", but here's my interpretation: http://jsfiddle.net/ebiewener/NknCW/2/
We essentially just bind the keydown event to the page and check if either of the keys pressed were the up or down arrow:
$(function(){
$(document).keydown(function(e){
if(e.which === 38){ //up
var currentLI = $('li.selected');
var currentLIprev = currentLI.prev();
if(currentLI.length > 0 && currentLIprev.length > 0){
currentLI.removeClass('selected');
currentLIprev.addClass('selected');
}else{
$('li:first').addClass('selected');
}
}else if(e.which === 40){ //down
var currentLI = $('li.selected');
var currentLInext = currentLI.next();
if(currentLI.length > 0){
if(currentLInext.length > 0){
currentLI.removeClass('selected');
currentLInext.addClass('selected');
}
}else{
$('li:first').addClass('selected');
}
}
});
});