I have website with a javaScript function that should scroll to section on page when user clicks a navigation item. This script worked before I made changes to my nav menu. I can not figure out how to reference the ID's in the javaScript correctly.
Here is HTML nav menu:
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Data Detective</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a id="home" href="#homeSect">HOME</a></li>
<li><a id="about" href="#aboutSect">ABOUT</a></li>
<li><a id="portfolio" href="#portfolioSect">PORTFOLIO</a></li>
<li><a id="contact" href="#contactSect">CONTACT</a></li>
</ul>
</div>
</div>
</div>
Here is the javaScript:
$(document).ready(function() {
setBindings();
});
//Allow screen to Scroll to selected section
function setBindings() {
$("nav ul li a").click(function (tip) {
tip.preventDefault();
var sectionID = "#" + tip.currentTarget.id + "Sect";
alert('button id ' + sectionID);
$("html body").animate({
scrollTop: $(sectionID).offset().top
}, 1000);
});
}
You should use .navbar class.
Please change:
$("nav ul li a").click(function (tip) {
TO
$(".navbar ul li a").click(function (tip) {
Further more, I recommend you to use var sectionID = $(this).attr('href'); instead var sectionID = "#" + tip.currentTarget.id + "Sect"; because it's more simply.
Your jQuery selector:
$("nav ul li a")
will search for the element <nav> (which doesn't exist).
Instead, you can use the selector:
$(".nav a")
I would do a more useful global function I guess. I would check for any href with an anchor reference, check if there is a div with that id, and then scroll to that one.
That way you're not limited to the menu but can use the same code everywhere. Also I made the event caputurer the top level document, so you can insert and remove elements at hearts content and it will always work without having to be rebound.
$(document).on('click','a[href^="#"]',function(e) {
var target = $(e.currentTarget).attr('href');
var $target = $(target);
if($target.length > 0) {
$("html body").animate({
scrollTop: $target.offset().top
}, 1000);
}
});
div.sect {
margin:50px;
height:400px;
width:100%;
background-color:gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li><a id="blah" href="www.google.nl">Excluded</a></li>
<li><a id="home" href="#homeSect">HOME</a></li>
<li><a id="about" href="#aboutSect">ABOUT</a></li>
<li><a id="portfolio" href="#portfolioSect">PORTFOLIO</a></li>
<li><a id="contact" href="#contactSect">CONTACT</a></li>
<li><a id="blah" href="www.google.nl">Excluded</a></li>
<div class="sect" id="portfolioSect">
portfolioSect
</div>
<div class="sect" id="homeSect">
homeSect
</div>
<div class="sect" id="aboutSect">
aboutSect
</div>
<div class="sect" id="contactSect">
contactSect
</div>
Related
I am using this js to scroll to the id of the page. I took it from w3 schools and it works on my other site, so I don't understand why it doesn't work on my new site. It goes to the correct part of the page, but it doesn't do the scroll animation.
js:
<script>
$(document).ready(function () {
$(".navbar a, footer a[href='#myPage']").on('click', function (event) {
if (this.hash !== "") {
event.preventDefault();
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function () {
window.location.hash = hash;
});
}
});
})
</script>
html navbar code:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li>ABOUT</li>
<li>CLIENTS</li>
<li>SESSIONS</li>
<li>CONTACT</li>
</ul>
</div>
</div>
</nav>
Please let me know if you need to see any other code. Thanks!
That should work.
Are you positive that the new site is using jQuery and that the IDs of the element that you are scrolling to are correct?
Is your console displaying an error?
I have this code
jQuery(function($) {
'use strict';
$(window).scroll(function(event) {
Scroll();
});
$('.navbar-collapse ul li a').on('click', function() {
$('html, body').animate({
scrollTop: $(this.hash).offset().top - 5
}, 1000);
return false;
});
function Scroll() {
var contentTop = [];
var contentBottom = [];
var winTop = $(window).scrollTop();
var rangeTop = 200;
var rangeBottom = 500;
$('.navbar-collapse').find('.scroll a').each(function() {
contentTop.push($($(this).attr('href')).offset().top);
contentBottom.push($($(this).attr('href')).offset().top + $($(this).attr('href')).height());
})
$.each(contentTop, function(i) {
if (winTop > contentTop[i] - rangeTop) {
$('.navbar-collapse li.scroll')
.removeClass('active')
.eq(i).addClass('active');
}
})
};
I tried keep getting this error when loading the code:
Uncaught TypeError: Cannot read property 'top' of undefined.
The effected lines are 9 and 21
Just in case this helps, the site this code is loading on works fine as it's html file, but doesn't when its set up as a WHMCS theme
The HTML this should be working with is
<nav id="main-nav" class="navbar navbar-default navbar-fixed-top" role="banner">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.php"><img src="templates/six/images/logo.png" alt="logo"></a>
</div>
<div class="collapse navbar-collapse navbar-right">
<ul class="nav navbar-nav">
<li class="scroll active">Home</li>
<li class="scroll">Features</li>
<li class="scroll">Services</li>
<li class="scroll">Domains</li>
<li class="scroll">Pricing</li>
<li class="scroll">Client Area</li>
<li class="scroll">Support</li>
</ul>
</div>
</div><!--/.container-->
</nav>
The problem is this:
$($(this).attr('href')).offset().top
You are sending the result of getting the href into the Jquery $function which will return an object with an undefined offset() as it's not part of the page.
$('my-a-tag').offset().top where my-a-tag finds your a tag uniquely will work, as long as my-a-tag exists on the page.
This jsfiddle here demonstrates. Open the console to see the difference between the object returned by your code and the object returned by the correct code. Also, see the offset() function working correctly.
Here's also an example line that should work in your code:
contentTop.push($(this).offset().top);
In this this case we just use this rather than a class like in the jsfiddle as we're in a loop which is going through all the anchors.
I am current changing a website to use Bootstrap and I have been advised that they want to use the navbar-inverse navbar-fixed-top main menu.
The thing is I can't figure out how to highlight the selected page and keep it highlighted.
I have tried the follow Jquery but I cant get none of them working
$(function() {
$('#nav li a').click(function() {
$('#nav li').removeClass();
$($(this).attr('href')).addClass('active');
});
});
My HTML for my menu is:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" runat="server" href="~/">Logo Here</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a runat="server" href="~/"><span class="glyphicon glyphicon-home"></span></a></li>
<li style="border-left: 1px solid lightgray"><a runat="server" href="~/About">About</a></li>
<li style="border-left: 1px solid lightgray"><a runat="server" href="~/Session/pg1">Session</a></li>
<li style="border-left: 1px solid lightgray"><a runat="server" href="~/EmailPg">Email</a></li>
</ul>
<asp:LoginView runat="server" ViewStateMode="Disabled">
<AnonymousTemplate>
<ul class="nav navbar-nav navbar-right">
<li><a runat="server" href="~/Contact">Contact us</a></li>
</ul>
</AnonymousTemplate>
</asp:LoginView>
</div>
</div>
</div>
I would prefer if its possible to do it with CSS or Jquery but I was also a little confused as, do I add the Jquery to every page OR can I add one lot to my Site.Master file
You were not selecting the active li tag correctly.
Instead I suggest you use something like this:
$(function() {
$('#nav li a').click(function() {
$(this).closest('li') // select the parent <li> tag
.addClass('active')// add the active class
.siblings() // select the siblings of the active tag
.removeClass('active'); // remove the active class from the other <li>
});
});
Fixed by adding the below JQuery to my Site.Master file
var url = window.location;
// Will only work if string in href matches with location
$('ul.nav a[href="' + url + '"]').parent().addClass('active');
// Will also work for relative and absolute hrefs
$('ul.navbar-nav a').filter(function () {
return this.href == url;
}).parent().addClass('active');
I am trying to fade in the navigation bar and stick to top while scrolling to bottom of the page. Its fade effect works only the first time. My code is below.
<style type="text/css">
.navOpacity{
opacity: 0;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(window).scroll(function(){
var ht = $('header').height()+70;
if($(this).scrollTop() >= ht){
$("#navb").addClass("navbar-fixed-top navOpacity")
.fadeTo('slow','1');
$(".row:first").css("padding-top","50px");
}else{
$("#navb").removeClass("navbar-fixed-top navOpacity");
$(".row:first").css("padding-top","0px");
}
});
});
</script>
<div class="container">
<header class="page-header">
<h1>Hello world</h1>
</header>
<nav id="navb" class="navbar navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
<a class="dropdown-toggle"
data-toggle="dropdown" href="#">Page 1
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Page 1-1</li>
<li>Page 1-2</li>
<li>Page 1-3</li>
</ul>
</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
</div>
</nav>
<div class="row">
<div class="col-md-4">
<h3>h1. Bootstrap heading</h3>
Hello world and Mario.
</div>
<div class="col-md-4">
<h3>h2. Bootstrap heading</h3>
Hello world and Mario.
</div>
<div class="col-md-4">
<h3>h3. Bootstrap heading</h3>
Hello world and Mario.
<img src="rsz_myimg.jpg" class="img-responsive" />
</div>
</div><!-- end or row class-->
</div><!-- end container class-->
Your problem is that after the first time fadeTo is executed, your element is left with a style="opacity: 1" attribute, which is left there. So you have to remove it when you scroll to the top.
I've also changed the way the navbar is hidden, I suggest using .hide(), cause it also uses the elements' style attribute, that way it will not be overridden. And there's also a navbarVisible var that is used to determine if the navbar is already faded in and if it is, the code for fading it in is not executed when not needed. This should be a tiny step up in performance.
This seems to work just fine:
<script type="text/javascript">
$(document).ready(function(){
var navbarVisible = false;
$(window).scroll(function(){
var ht = $('header').height()+70;
if ($(this).scrollTop() >= ht) {
if (!navbarVisible) {
$("#navb").addClass("navbar-fixed-top")
.hide()
.fadeTo('slow','1');
$(".row:first").css("padding-top","50px");
navbarVisible = true;
};
} else {
$("#navb").removeClass("navbar-fixed-top").removeAttr('style');
$(".row:first").css("padding-top","0px");
navbarVisible = false;
}
});
});
</script>
You don't need this part anymore:
<style type="text/css">
.navOpacity{
opacity: 0;
}
</style>
Here's a link to an example JSFiddle with working code: JSFiddle Link
My two cents...
Just add this Javascript and away you go. Currently configured to graduate over the first 200px of scroll.
var scrollFadePixels = 200;
var fadeNavbar = function (window)
{
var opacity = window.scrollTop() / scrollFadePixels;
$('.navbar-fixed-top').css('background-color', 'rgba(34,34,34,' + opacity + ')');
}
fadeNavbar($(window));
$(window).scroll(function () {
fadeNavbar($(this));
});
Question Background:
I have a standard bootstrap NavBar that collpases to a button on mobile devices.
The Issue:
When the user clicks on an item in the NavBar dropdown list the page will scroll down to the corrosponding div. I have a piece of JQuery that collpases the dropdown menu when the item has been clicks.
Without the JQuery to close the dropdown Nav menu the page scrolls down to the div with no issues. With the JQuery the page is scrolling down but stops well after the set 10px offset.
Without the JQuery menu closing code - working:
Note the small 10px above the panel item, this is what is wanted.
With the JQuery closing code - Broken:
Note that the page now scrolls down past the top of the div.
The Code:
The NavBar:
<div class="navbar">
<nav class="navbar navbar-default navbarColour" role="navigation" id="nav">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<img src="~/Images/DC.png" class="dc">
</div>
<div class="middleNavPadding">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav pull-right">
<li>Services</li>
<li>Our Mission</li>
<li>Projects Gallery</li>
<li>Contact Us</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
The JQuery Menu closing code:
$(document).ready(function () {
$(".navbar-nav .scroll-link").click(function (event) {
$(".navbar-collapse").collapse('hide');
});
});
The JQuery used to scroll to the Div as set in the NavBar menu:
$(document).ready(function () {
$('.scroll-link').on('click', function (event) {
event.preventDefault();
var sectionID = $(this).attr("data-id");
scrollToID('#' + sectionID, 750);
});
function scrollToID(id, speed) {
var offSet = 10;
var targetOffset = $(id).offset().top - offSet;
$('html,body').animate({ scrollTop: targetOffset }, speed);
}
});
The HTML Markup of the Panel:
<div id="Info">
//panel HTML
</div>
I believe the issue is that the JQuery is setting the 'top' of the page as the bottom of the dropdown menu which is then causing a false offset. Any help with solving a a solution to this would be much appreciated.
You are on the right track, just add the height of the #bs-example-navbar-collapse-1 to your offset.
function scrollToID(id, speed) {
var offSet = 10 + $('#bs-example-navbar-collapse-1').height(); // NAVBAR HEIGHT !!!
var targetOffset = $(id).offset().top - offSet;
$('html,body').animate({ scrollTop: targetOffset }, speed);
}
This should work.