Make One NAV link active across multiple sections (using classes???) - javascript

I need to have only one nav link in active state when a user goes through multiple sections of my website. How do I make the proper edits to this JS to make that happen?
For instance, if the default nav link id = #dinos_
I want all my sections that use section ids like #dinos_trex, #dinos_raptor, #dinos_triceratops to keep making the nav id that = #dinos_ to stay in the active state in the nav.
After further research, would someone be able to code something with 'classes'?
Lets say a set of divs share a certain class name, in this case "dinos_" how can I set an active state for just one nav item if the user is on 'any' of the related "dinos_" sections????
here is the current jquery Im using:
var sections = $('section'), nav = $('nav'), nav_height = nav.outerHeight();
$(window).on('scroll', function () {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top - nav_height,
bottom = top + $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find('a').removeClass('active');
sections.removeClass('active');
$(this).addClass('active');
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
});
});
Im guessing this snippet of code in particular is where I need someone to help me redefine?
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
Here is my HTML
<header id="header">
<!-- Nav -->
<nav id="nav">
<ul>
<li>DINOS</li> /*multiple unique section ids that contain the word dinos_ in their id name should set this to 'active */
<li>ROBOTS</li> /*multiple unique section ids that contain the word robots_ in their id name should set this to 'active */
<li>UNDEAD</li> /*multiple unique section ids that contain the word undead_ in their id name should set this to 'active */
</ul>
</nav>
</header>
<section id="dinos_" class="main style2 right dark fullscreen">
<div class="content box style2">
<header>
<h2>DINOSAURS INTRO</h2>
</header>
<p>
Intro to the dinos</p>
</div>
up
down
</section>
<section id="dinos_trex" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>T-REX</h2>
</header>
<p>
Section for the T-rex</p>
</div>
up
down
</section>
<section id="dinos_raptor" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE RAPTOR</h2>
</header>
<p>
Section for the raptor/p>
</div>
up
down
</section>
<section id="robots_" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>ROBOTS INTRO</h2>
</header>
<p>
Section for the Robots Intro</p>
</div>
up
down
</section>
<section id="robots_gunner" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE ROBOT GUNNER</h2>
</header>
<p>
Section for the gunner</p>
</div>
up
down
</section>

Using the waypoints plugin:
http://imakewebthings.com/waypoints/
UPDATED
JS:
$('section').waypoint({
handler: function (direction) {
$(".active").removeClass("active");
$("nav a[href=\"#" +this.element.id + "\"").addClass("active");
}
});
HTML with some minor changes:
<header id="header">
<!-- Nav -->
<nav id="nav">
<ul>
<li>DINOS
</li>
<li>ROBOTS
</li>
<li>UNDEAD
</li>
</ul>
</nav>
</header>
<section id="dinosaurs" class="main style2 right dark fullscreen">
<div class="content box style2">
<header>
<h2>DINOSAURS INTRO</h2>
</header>
<p>Intro to the dinos</p>
</div> up
down
</section>
<section id="dinosaurs_trex" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>TREX</h2>
</header>
<p>Section for the Trex</p>
</div> up
down
</section>
<section id="dinosaurs_raptor" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE RAPTOR</h2>
</header>
<p>Section for the Trex</p>
</div> up
down
</section>
Here's a fiddle:
http://jsfiddle.net/4qwawrgx/

change your this code
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
to this
function activateNav() {
var hashValue = window.location.hash.substr(1);
$('body').find('a[href="#'+ hashValue +'"]').addClass('active');
}
$( document ).ready(function() {
activateNav();
$('a').on('click', function() {
activateNav();
});
});

Related

how to find the id of the element anchored in a link when user click on the link (JavaScript)

This is a landing page project. it has 5 html sections. it also has a dynamic navigation bar at the top that links the sections. whenever a section is added in the html it is updated on the navigation bar and links you to the section that you clicked on.
I want to use JavaScript to add smooth scrolling behavior whenever I click on the sections (like scrollIntoView())
here is the html of a section
let navList = document.querySelector('#navbar__list'); // stores the <ul>...</ul>
let sectionsNumber = document.querySelectorAll('h2');
const makeNavListItems = () => {
for (let i = 0; i < sectionsNumber.length; i++) {
listItem = document.createElement('li');
listItem.innerHTML = ` <a class="menu__link" href="#section${i+1}"> Section ${i+1} </a>`;
navList.appendChild(listItem);
}
};
<!-- HTML Follows BEM naming conventions
IDs are only used for sections to connect menu achors to sections -->
<header class="page__header">
<nav class="navbar__menu">
<!-- Navigation starts as empty UL that will be populated with JS -->
<ul id="navbar__list"> </ul>
</nav>
</header>
<main>
<header class="main__hero">
<h1>Landing Page </h1>
</header>
<section id="section1" data-nav="Section 1" class="your-active-class">
<div class="landing__container">
<h2>Section 1</h2>
<p>.....</p>
<p>.......</p>
</div>
I must use an event Listener to add this scrolling behavior (project requirement)
so i was thinking of something like this
navList.addEventListener('click',function(event){
event.preventDefault();
if(event.target.href){document.getElementById().scrollIntoView({behavior:'smooth'})} })
so this will check if the event target is a link.
the problem is I can't find a way to get the id of the element anchored in the link
const navList = document.querySelector('#navbar__list');
const sectionsNumber = document.querySelectorAll('h2');
const makeNavListItems = () => {
for (let i = 0; i < sectionsNumber.length; i++) {
listItem = document.createElement('li');
listItem.innerHTML = ` <a class="menu__link" href="#section${i+1}"> Section ${i+1} </a>`;
navList.appendChild(listItem);
}
};
makeNavListItems();
navList.addEventListener('click', function(event) {
event.preventDefault();
if (event.target.href) {
//here we use uditkumar11's idea to get the id (or rather the query string for getting the element with the id)
const idQueryStr = event.target.getAttribute('href');
console.log(idQueryStr);
const targetElem = document.querySelector(idQueryStr);
targetElem.scrollIntoView({
behavior: 'smooth'
});
}
});
<body>
<header class="page__header">
<nav class="navbar__menu">
<ul id="navbar__list">
</ul>
</nav>
</header>
<main>
<header class="main__hero">
<h1>Landing Page</h1>
</header>
<section id="section1" data-nav="Section 1" class="your-active-class">
<div class="landing__container">
<h2>Section 1</h2>
<p>.....</p>
<p>.......</p>
</div>
</section>
</main>
</body>

The problem is when I click on the link in the Navbar it doesn't go to its section

I am trying to make a dynamic navbar and when I click on the link it goes to its specific section and I used the following code:
//scroll to section when click on nav links
li_links.addEventListener('click', e => {
e.preventDefault();
section.scrollIntoView()
});
Why when I click on the link it goes to the end of the page and not to the specified section?
This is the code:
const Ul = document.querySelector('ul');
const sections = document.querySelectorAll('section');
for(section of sections) {
//create li:
const li_items = document.createElement("li");
//create new anchor elements:
const li_links = document.createElement("a");
//give anchor elements a hyperlinks:
const IdAttribute = section.getAttribute('id');
li_links.setAttribute('href', IdAttribute);
//get the names of the sections:
const navData = section.getAttribute("data-nav");
const text = document.createTextNode(navData);
//give the navbar style :
li_links.classList.add("menu__link");
Ul.appendChild(li_items);
li_items.appendChild(li_links);
li_links.appendChild(text);
//scroll to section when click on nav links
li_links.addEventListener('click', e => {
e.preventDefault();
section.scrollIntoView()
});
}
//end of the navbar.
HTML Code:
<header id="hdr" class="page__header">
<nav class="navbar__menu">
<!-- Navigation starts as empty UL that will be populated with JS -->
<ul id="navbar__list"></ul>
</nav>
</header>
<main>
<header class="main__hero">
<h1>Landing Page </h1>
</header>
<section id="section1" data-nav="Section 1" class="your-active-class">
<div class="landing__container">
<h2>Section 1</h2>
<p></p>
<p></p>
</div>
</section>
<section id="section2" data-nav="Section 2">
<div class="landing__container">
<h2>Section 2</h2>
<p></p>
<p></p>
</div>
</section>
<section id="section3" data-nav="Section 3">
<div class="landing__container">
<h2>Section 3</h2>
<p></p>
<p></p>
</div>
</section>
<section id="section4" data-nav="Section 4">
<div class="landing__container">
<h2>Section 4</h2>
<p></p>
<p></p>
</div>
</section>
code on codepen:
CodePen
Use const or let to declare a block scoped variable
for(const section of sections) {
Otherwise the section is in the function scope, and it is re-assigned for each iteration of the loop. So when the events happen they will point to the last value of section.
Read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#description

display current tab javascript

I have a tabbed section that changes the content when selecting a new tab but I want it to always show the home tab when the pages loads. Right now, no tabs displays when the page loads. I want the home tab to show when you first visit the page, Thanks!
Here is the codepen https://codepen.io/emberwolves/pen/rorEmK
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<section id="tabbed-wrapper">
<div id="navSection">
Home
Work
About
Contact
</div>
<div id="sections">
<div id="home" class="tabs">
<h4>Home Section</h4>
<p>Welcome. Rather see a CSS only version?</p>
<p>Check it out here</p>
</div>
<div id="work" class="tabs">
<h4>Work Section</h4>
<p>For a pure CSS version check out here</p>
</div>
<div id="about" class="tabs">
<h4>About Section</h4>
<p>This was a quick little pen for fun. Don't mind the ugly styling.</p>
</div>
<div id="contact" class="tabs">
<h4>Contact Section</h4>
<p>Some random contact details...</p>
</div>
</div>
</section>
//nav links
const links = document.querySelectorAll('.navLink');
//Tabbed sections
const tabs = document.querySelectorAll('.tabs');
links.forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
//remove current class from inactive links
for(let j = 0; j < links.length; j++) {
links[j].classList.remove('current');
}
//add current class to active link
e.target.classList.add('current');
//used to store the target ID in string format
let target = e.target.textContent.toLowerCase();
for(let i = 0; i < tabs.length; i++) {
tabs[i].classList.remove('active')
}
//Show active tab
document.getElementById(target).classList.toggle('active');
}, false)
});
Just add initial classes in your html:
1) First place is nav menu:
Home
2) Second place is home tab:
<div id="home" class="tabs active">
<h4>Home Section</h4>
<p>Welcome. Rather see a CSS only version?</p>
<p>Check it out here</p>
</div>
Full example:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<section id="tabbed-wrapper">
<div id="navSection">
Home
Work
About
Contact
</div>
<div id="sections">
<div id="home" class="tabs active">
<h4>Home Section</h4>
<p>Welcome. Rather see a CSS only version?</p>
<p>Check it out here</p>
</div>
<div id="work" class="tabs">
<h4>Work Section</h4>
<p>For a pure CSS version check out here</p>
</div>
<div id="about" class="tabs">
<h4>About Section</h4>
<p>This was a quick little pen for fun. Don't mind the ugly styling.</p>
</div>
<div id="contact" class="tabs">
<h4>Contact Section</h4>
<p>Some random contact details...</p>
</div>
</div>
</section>
you need to add click method on it .
document.getElementById("test2").click();
For more info.
And also you need to add id or class to your html tag
Home
your codepen edited.
https://codepen.io/anon/pen/aPjebe

How Do I Stop Static Sidebar at Footer

I have a static sidebar on scroll but when it reaches the footer it overlaps. Is there a way for me to stop this scrolling onto the footer? I understand this may be a simple concept but I have little experience working with the Scroll event in JQuery so any help would be fantastic.
Please find my code and a CodePen below.
<div id="main">
<div class="spacing">CONTENT HERE TO SHOW HOW THE SCROLL WILL WORK. PLEASE SCROLL DOWN</div>
<div class="container">
<div id="sidebar">
<div id="nav-anchor"></div>
<nav>
<ul>
<li>Blue</li>
<li>Green</li>
<li>Red</li>
<li>Yellow</li>
<li>Purple</li>
</ul>
</nav>
</div>
<!-- /sidebar -->
<div id="content">
<section id="blue">
...
</section>
<section id="green">
...
</section>
<section id="red">
...
</section>
<section id="yellow">
...
</section>
<section id="purple">
...
</section>
</div>
<!-- /#content -->
</div>
<!-- /.container -->
<footer>
<p>Footer here</p>
</footer>
</div>
<!-- /#main -->
$(document).ready(function(){
$(window).scroll(function(){
var window_top = $(window).scrollTop() + 12;
var div_top = $('#nav-anchor').offset().top;
if (window_top > div_top) {
$('nav').addClass('stick');
} else {
$('nav').removeClass('stick');
}
});
});
http://codepen.io/harryberry94/pen/MyOezg
If you want to hide the static element when it is overlapping the footer, add one more condition in your if condition after $('nav').addClass('stick'); :
var footer_top = $("footer").offset().top;
var static_div_bottom = $('nav').offset().top + $('nav').height();
$('#abc').text(footer_top +" " + static_div_bottom +" " + window_top);
if(static_div_bottom > footer_top){
$('nav').removeClass('stick');
}
You can use css for that if all you want is for your div not to overlap the footer, no need to use javascript and the scroll event. Just add z-index:-1; for nav.stick. Also if it needs a greater z-index to go over other elements in the page you can give the footer position:absolute; and a greater z-index (to keep content from going under the footer add padding-bottom to the body element).

Change "selected" on scroll in page

I've been trying to get the automatic update on my navbar but i cant get it to work.
Here is my code: http://pastebin.com/YTHaBD0i
<div id="header">
<ul class="nav-list">
<li class="download selected">Download</li>
<li class="features">Features</li>
<li class="method">Method</li>
<li class="purchase">Purchase</li>
</ul>
</div>
<div id="footer">yey productions © 2016</div>
<div id="fullpage">
<div class="section " id="section0">
<div class="intro">
<h1>Download</h1>
<p>Lorem Ipsum</p>
</div>
</div>
<div class="section" id="section1">
<div class="slide" id="slide1">
<div class="intro">
<h1>Features</h1>
<p>Cheese.</p>
</div>
</div>
<div class="slide" id="slide2">
<h1>Cheese2</h1>
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<h1>Yey</h1>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<h1>Yey2</h1>
</div>
</div>
</div>
Help would be much appreciated!
Greetz,
Assuming you are using jQuery, you will need a function that fires every time you scroll.
From there, you need to detect which elements are in view.
Once you know which elements are in view, clear any currently active elements with the .selected class, then choose which one you want to be .selected and add the .selected class.
Edit for more detail:
Below is a pure JavaScript solution, which I found here. This should be close to a drop-in solution!:
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.selected').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'selected');
}
}
};
})();

Categories

Resources