I have been staring at this code for far too long, unfortunately I do not see the problem.
I am trying to get the active menu entry highlighted when the relevant div gets scrolled into view. But nothing is happening and no errors are being thrown in the console.
My menu html:
<section class="LeftAnchorNav" style="display: block;">
<nav id="LeftAnchorNav">
<div class="container" style="padding-left: 50px;">
<div class="col-md-4 LeftAnchorNavWrapper">
<ul class="LeftAnchorNavMenu">
<li class="leftanchorlink">
<a class="leftlink" href="#20a51af3-f8b0-4ef9-ba73-cf3cd0a321b9">About us</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#d736bc13-a2a7-48d4-8ecc-75b9a17f801b">Demo Center</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#545a6339-87e4-41ed-ad51-70c3788cedee">Testimonial</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#9355324a-6219-4300-ae97-aa77bf67dab4">Newsletter</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#0c70b0db-3e70-4faa-ab98-154b4eae498e">Blog</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#4903bc53-b862-42f0-a600-e21061204e42">Contact</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#002f6fd7-758b-4b27-8c75-0ce087ee826a">Solution Finder</a>
</li>
</ul>
</div>
</div>
</nav>
</section>
An example div:
<div class="block anchorblock col-lg-12 col-md-12 col-sm-12 col-xs-12 span12 "><div id="20a51af3-f8b0-4ef9-ba73-cf3cd0a321b9"></div>
</div>
My jquery/js:
if ($('.LeftAnchorNav').length > 0) {
// prepare the variables
var lastID;
var anchorMenu = $(".LeftAnchorNavMenu");
var anchorMenuHeight = anchorMenu.outerHeight() + 100;
var anchorMenuItems = anchorMenu.find(".leftlink");
var anchorMenuItemsTarget = anchorMenuItems.map(function () {
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
// bind everything to the scrolling
$(window).scroll(function () {
// get anchornav container scroll position and add buffer
var fromTop = $(this).scrollTop() + anchorMenuHeight + 300;
// get ID of the current scroll item
var currentItem = anchorMenuItemsTarget.map(function () {
if ($(this).offset().top < fromTop)
return this;
});
// get the ID of the current element
currentItem = currentItem[currentItem.length - 1];
var id = currentItem && currentItem.length ? currentItem[0].id : "";
if (lastID !== id) {
lastID = id;
// Set/remove active class
anchorMenuItems.removeClass("highlightleftnavactive")
anchorMenuItems.filter("[href='#" + id + "']").addClass("highlightleftnavactive");
}
});
}
It's quite fiddly to do the arithmetic for scrolling so this snippet uses IntersectionObserver instead. This has the added benefit of less processing overhead as it just gets informed when the elements come in or go out of view, not every time the user scrolls a bit.
It sets up the observer to observe when any of the relevant elements come into or go out of the viewport. When alerted to that it adds or removes the highlighting class to the related navbar link.
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<style>
.LeftAnchorNav {
position: fixed;
z-index:1;
}
.tall {
width: 100vw;
height: 100vh;
background-image: linear-gradient(cyan, magenta, yellow, black);
}
.highlightleftnavactive {
background-color: yellow;
}
</style>
</head>
<section class="LeftAnchorNav" style="display: block;">
<nav id="LeftAnchorNav">
<div class="container" style="padding-left: 50px;">
<div class="col-md-4 LeftAnchorNavWrapper">
<ul class="LeftAnchorNavMenu">
<li class="leftanchorlink">
<a class="leftlink" href="#20a51af3-f8b0-4ef9-ba73-cf3cd0a321b9">About us</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#d736bc13-a2a7-48d4-8ecc-75b9a17f801b">Demo Center</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#545a6339-87e4-41ed-ad51-70c3788cedee">Testimonial</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#9355324a-6219-4300-ae97-aa77bf67dab4">Newsletter</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#0c70b0db-3e70-4faa-ab98-154b4eae498e">Blog</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#4903bc53-b862-42f0-a600-e21061204e42">Contact</a>
</li>
<li class="leftanchorlink">
<a class="leftlink" href="#002f6fd7-758b-4b27-8c75-0ce087ee826a">Solution Finder</a>
</li>
</ul>
</div>
</div>
</nav>
</section>
<div class="tall"></div>
<div class="block anchorblock col-lg-12 col-md-12 col-sm-12 col-xs-12 span12 "><div id="20a51af3-f8b0-4ef9-ba73-cf3cd0a321b9">
An example block coming into and going out of view it belongs to the About us link in the navbar</div>
</div>
<div class="tall"></div>
<script>
let callback = (entries) => {
entries.forEach(entry => {
let id = entry.target.firstChild.id;
let leftLink = document.querySelector("a.leftlink[href='#"+ id + "']");
if (entry.isIntersecting) { leftLink.classList.add('highlightleftnavactive');}
else { leftLink.classList.remove('highlightleftnavactive');}
});
};
const observer = new IntersectionObserver(callback);
const anchorBlocks = document.querySelectorAll('.anchorblock');
anchorBlocks.forEach( (anchorBlock) => {
observer.observe(anchorBlock);
});
</script>
Related
I'm trying to create an e-shop and I want different categories to show up when a div is active.
JAVASCRIPT:
const tab_switchers = document.querySelectorAll('[data-switcher]');
for (let i = 0; i < tab_switchers.length; i++) {
const tab_switcher = tab_switchers[i];
const page_id = tab_switcher.dataset.tab;
tab_switcher.addEventListener('click', () => {
document.querySelector('.sidenav .tabs .tab.is-active').classList.remove('is-active');
tab_switcher.parentNode.classList.add('is-active');
SwitchPage(page_id);
});
}
}
function SwitchPage (page_id) {
const current_page = document.querySelector('.pages .page.is-active');
current_page.classList.remove('is-active')
const next_page = document.querySelector(`.pages .page[data-page="${page_id}]`);
next_page.classList.add('is-active');
}
HTML: ```
<ul class="tabs"></ul>
<li class="tab is-active">
<a data-switcher data-tab="1">Dell</a>
</li>
<li class="tab">
<a data-switcher data-tab="2">Apple</a>
</li>
<li class="tab">
<a data-switcher data-tab="3">HP</a>
</li>
<li class="tab">
<a data-switcher data-tab="4">Toshiba</a>
</li>
<li class="tab">
<a data-switcher data-tab="5">Lenovo</a>
</li>
<li class="tab">
<a data-switcher data-tab="6">Acer</a>
</li>
<li class="tab">
<a data-switcher data-tab="7">Asus</a>
</li>
<li class="tab">
<a data-switcher data-tab="8">Microsoft</a>
</li>
```
I don't know what else to do or look for, I'm still in javascript but I followed an exact tutorial and worked for him
many mistake from your example code: <ul class="tabs"></ul> is closed not including li, onst next_page = document.querySelector(.pages .page[data-page="${page_id}]); quote for page_id is not properly closed.
Here is the working snippet from your example code.
const tab_switchers = document.querySelectorAll('[data-switcher]');
for (let i = 0; i < tab_switchers.length; i++) {
const tab_switcher = tab_switchers[i];
const page_id = tab_switcher.dataset.tab;
tab_switcher.addEventListener('click', (event) => {
document.querySelector('.tabs .tab.is-active').classList.remove('is-active');
tab_switcher.parentNode.classList.add('is-active');
SwitchPage(page_id);
});
}
function SwitchPage (page_id) {
const current_page = document.querySelector('.pages .page.is-active');
current_page.classList.remove('is-active')
const next_page = document.querySelector(`.pages .page[data-page="${page_id}"]`);
next_page.classList.add('is-active');
}
ul.tabs {
display:flex;
padding:0;
margin:0;
}
ul.tabs li {
list-style:none;
margin-right:10px;
cursor:pointer;
}
ul.tabs li.is-active {
text-decoration:underline;
}
.pages .page {
display:none;
}
.pages .page.is-active {
display:block;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<ul class="tabs">
<li class="tab is-active">
<a data-switcher data-tab="1">Dell</a>
</li>
<li class="tab">
<a data-switcher data-tab="2">Apple</a>
</li>
<li class="tab">
<a data-switcher data-tab="3">HP</a>
</li>
</ul>
<div class="pages">
<div class="page is-active" data-page="1">Page Dell</div>
<div class="page" data-page="2">Page Apple</div>
<div class="page" data-page="3">Page HP</div>
</div>
Problem
I have an issue with my website, I want to change the color of the selected link to blue, and if other is selected put it back to gray, but don`t know how to target the clicked link in javascript. Here is my code.
var center = document.getElementsByClassName("center");
for (let i = 0; i < center.length; i++) {
center[i].addEventListener("click", DivSelector());
}
function DivSelector() {
for (let i = 0; i < center.length; i++) {
center[i].classList.Remove('active');
};
}
.nav-item {
text-decoration: none;
color: #505b67;
margin-left: 10px;
}
.active {
color: #4460f1;
}
<ul class="nav-tab-ul">
<li id="Profile">
<a class="center nav-item" href="">Profile</a>
</li>
<li id="Change-Password">
<a class="center nav-item" href="">Change password</a>
</li>
<li id="Notifications">
<a class="center nav-item" href="">Notifications</a>
</li>
<li id="My-Cards">
<a class="center nav-item" href="">My Cards</a>
</li>
</ul>
Don`t know how to select the clicked link here for adding the 'active' class.
Try this. its working
var center = document.getElementsByClassName("center");
for (let i = 0; i < center.length; i++) {
center[i].addEventListener("click", function(e){
for (let i = 0; i < center.length; i++) {
center[i].classList.remove('active');
e.target.classList.add('active');
}
})
}
All you need to do is add the class active to the actual link of the page you are on. So when you on the profile page you add active to profile link and none of the others
PROFILE PAGE
<ul class="nav-tab-ul">
<li id="Profile">
<a class="center nav-item active" href="">Profile</a>
</li>
<li id="Change-Password">
<a class="center nav-item" href="">Change password</a>
</li>
<li id="Notifications">
<a class="center nav-item" href="">Notifications</a>
</li>
<li id="My-Cards">
<a class="center nav-item" href="">My Cards</a>
</li>
</ul>
CHANGE PASSWORD PAGE
When you on the change password page you add the active class to that link and none of the others.
<ul class="nav-tab-ul">
<li id="Profile">
<a class="center nav-item" href="">Profile</a>
</li>
<li id="Change-Password">
<a class="center nav-item active" href="">Change password</a>
</li>
<li id="Notifications">
<a class="center nav-item" href="">Notifications</a>
</li>
<li id="My-Cards">
<a class="center nav-item" href="">My Cards</a>
</li>
</ul>
If these are separate pages there is no need for JS?
If you are using one header file and including the file into all your pages then it will be a different solution. Let us know why you want to use JS
You can get the element clicked in event.currentTarget.
const nodes = document.getElementsByClassName("center");
for (let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener("click", divSelector);
}
function divSelector(event) {
removeAllActives();
event.currentTarget.className += ' active';
}
function removeAllActives() {
const actives = document.getElementsByClassName("active");
for (let i = 0; i < actives.length; i++) {
actives[i].classList.remove('active');
}
}
.active {
color: blue;
}
<a class="center"> Link 1 </a> <br/>
<a class="center"> Link 2 </a>
A few things:
When adding your event listener, you called DivSelector, meaning you added the return value of DivSelector() as a listener, which is void. Instead just pass the name of the function you want to add as a listener.
You need to add the 'active' class to the clicked element after removing it from all the others. You can get the clicked element by using the event argument passed to your event listener. The element will be event.target.
DivSelector should be defined before it's used, so it should be moved above the rest of the code.
Here's an example:
function DivSelector(event) {
for (let i = 0; i < center.length; i++) {
center[i].classList.remove('active');
}
event.target.classList.add('active');
}
let center = document.querySelectorAll("center");
for (let i = 0; i < center.length; i++) {
center[i].addEventListener("click", DivSelector);
}
.nav-item {
text-decoration: none;
color: #505b67;
margin-left: 10px;
}
.active {
color: #4460f1;
}
<ul class="nav-tab-ul">
<li id="Profile">
<a class="center nav-item" href="#">Profile</a>
</li>
<li id="Change-Password">
<a class="center nav-item" href="#">Change password</a>
</li>
<li id="Notifications">
<a class="center nav-item" href="#">Notifications</a>
</li>
<li id="My-Cards">
<a class="center nav-item" href="#">My Cards</a>
</li>
</ul>
I would like display combobox on IE 11 by referring this article https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.0pattern/combobox-autocomplete-none.html
but for some reason i can not display the listbox items on IE but for other browsers it works fine. Any idea?
If I try to remove this line
this.domNode = domNode;
it shows me the list but not clickable.
javascript class
/*
* This content is licensed according to the W3C Software License at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*/
var Option = function (domNode, listboxObj) {
this.domNode = domNode;
this.listbox = listboxObj;
this.textContent = domNode.textContent;
this.textComparison = domNode.textContent.toLowerCase();
};
Option.prototype.init = function () {
if (!this.domNode.getAttribute('role')) {
this.domNode.setAttribute('role', 'option');
}
this.domNode.addEventListener('click', this.handleClick.bind(this));
this.domNode.addEventListener('mouseover', this.handleMouseover.bind(this));
this.domNode.addEventListener('mouseout', this.handleMouseout.bind(this));
};
/* EVENT HANDLERS */
Option.prototype.handleClick = function (event) {
this.listbox.setOption(this);
this.listbox.close(true);
};
Option.prototype.handleMouseover = function (event) {
this.listbox.hasHover = true;
this.listbox.open();
};
Option.prototype.handleMouseout = function (event) {
this.listbox.hasHover = false;
setTimeout(this.listbox.close.bind(this.listbox, false), 300);
};
HTML
<section>
<h2 id="ex_label">Example</h2>
<div role="separator" id="ex_start_sep" aria-labelledby="ex_start_sep ex_label" aria-label="Start of"></div>
<div id="ex1">
<div class="combobox-list">
<label for="cb1-input">Search</label>
<div class="group">
<input id="cb1-input" class="cb_edit" type="text"
role="combobox"
aria-autocomplete="none"
aria-expanded="false"
aria-haspopup="true"
aria-owns="cb1-listbox"
readonly
/>
<button id="cb1-button" tabindex="-1" aria-label="Open">
▽
</button>
</div>
<ul id="cb1-listbox" role="listbox" aria-label="Previous Searches">
<li id="lb1-01" role="option">weather</li>
<li id="lb1-02" role="option">salsa recipes</li>
<li id="lb1-03" role="option">cheap flights to NY</li>
<li id="lb1-04" role="option">dictionary</li>
<li id="lb1-05" role="option">baseball scores</li>
<li id="lb1-06" role="option">hotels in NY</li>
<li id="lb1-07" role="option">mortgage calculator</li>
<li id="lb1-08" role="option">restaurants near me</li>
<li id="lb1-09" role="option">free games</li>
<li id="lb1-10" role="option">gas prices</li>
<li id="lb1-11" role="option">classical music</li>
</ul>
</div>
</div>
<div role="separator" id="ex_end_sep" aria-labelledby="ex_end_sep ex_label" aria-label="End of"></div>
</section>
I need to enable and disable tab based select results.Below the code I am working.If device B status is On-Line I need to disable Device-V tab.How to implement this using JavaScript/jQuery.
jQuery:
if(result.includes("On-line") ){
$(selected_device_id).html("");
//Need to implement disable function here
$(selected_device_id).append(result+" ✅");
HTML File:
<div class="panel">
<br>
<ul class="nav nav-pills nav-tabs">
<li class="active">
<a
data-toggle="tab"
href="#Device-B"
onclick="document.getElementById('Object').value = '';
document.getElementById('first_i').value = '';
document.getElementById('second_i').value = '';
document.getElementById('third_i').value = '';">
<i>
<b>Device B</b>
</i>
</a>
</li>
<li>
<a
data-toggle="tab"
href="#Device-V"
onclick="document.getElementById('tr181_object').value = '';
document.getElementById('first_i').value = '';
document.getElementById('second_i').value = '';
document.getElementById('third_i').value = '';">
<i>
<b>Video</b>
</i>
</a>
</li>
</div>
$(document).ready(function()
{
var switch_ch = 0 ;
$(".linktoggle").on("click",function(){
i = $(this).index(".linktoggle") ;
if( $(".linktoggle").attr("href") === "#Device-B")
{
if( switch_ch === 0 )
{
$(".linktoggle:eq(0)").show();
$("li:eq(0)").show();
$(".linktoggle:eq(1)").hide();
$("li:eq(1)").hide();
switch_ch = 1 ;
}
else
{
$(".linktoggle:eq(1)").show();
$("li:eq(1)").show();
switch_ch = 0 ;
}
}
if( $(".linktoggle").attr("href") === "#Device-V")
{
$(".linktoggle:eq("+i +")").hide();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="panel">
<br>
<ul class="nav nav-pills nav-tabs">
<li class="active">
<a
class="linktoggle"
href="#Device-B" >
<i>
<b>Device B</b>
</i>
</a>
</li>
<li>
<a
class="linktoggle"
data-toggle="tab"
href="#Device-V"
>
<i>
<b>Video</b>
</i>
</a>
</li>
</div>
I need help for my personal website. I want to make a one page site with a fixed top navbar (with transparent background). At the scrolling of the page, the color of the menu elements must change dinamically from black to white on the sections that have a dark background (they have a ".dark-bg" class) and return white on the other sections. All sections are 100vh height (except for the menu, of course). This is the HTML main structure of the site:
<section class="section--menu fixed-header">
<nav class="menu" id="navigation">
<ul class="menu__list pull-md-right">
<li class="menu__item menu__item--current">
<a class="menu__link" data-target="intro-fabio">home</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="about-fabio">about</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="skills-fabio">skills</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="works-fabio">works</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="contacts-fabio">contacts</a>
</li>
</ul>
</nav>
</section>
<!-- HOME
======================================================== -->
<section id="intro-fabio">
</section>
<!-- ABOUT
======================================================== -->
<section id="about-fabio" class="dark-bg">
</section>
<!-- SKILLS
======================================================== -->
<section id="skills-fabio">
</section>
<!-- WORKS
======================================================== -->
<section id="works-fabio" class="dark-bg">
</section>
<!-- CONTACTS
======================================================== -->
<section id="contacts-fabio">
</section>
I wrote this jQuery script but it seems to work only for the last section with ".dark-bg" class.
$(document).ready(function() {
$(".dark-bg").each(function() {
detectBg( $(this) );
});
function detectBg(sezione) {
$(window).scroll(function() {
var finestra = $(window).scrollTop();
var sezCurr = sezione.offset().top;
var sezNext = sezione.next().offset().top;
if (finestra >= sezCurr && finestra < sezNext) {
$('.menu__link').css("color", "#ebebeb");
}
else {
$('.menu__link').css("color", "#1c1c1c");
}
});
}
});
Thanks in advance!
You need to handle scroll event of the window, and in that handler, check if any of the dark section is under the menu, if so, then change the color of the menu links. Here is an example of changing the color for all links, but it can be easily extended to do it separately for each link:
$(window).scroll(function() {
var vpHeight = $(window).height();
var isBlack = false;
$(".dark-bg").each(function(i, section) {
if(isBlack) {
return;
}
var offset = $(section).offset().top - $(window).scrollTop();
if(((offset + vpHeight) >= 0) && ((offset + vpHeight) <= vpHeight)) {
isBlack = true;
return;
}
});
$(".menu__link").css("color", isBlack ? "white" : "black");
});
body {
padding: 0;
margin: 0;
}
ul {
position:fixed;
background: orange;
padding: 0;
margin: 0;
list-style-type: none;
}
ul > li {
float: left;
padding: 0 4px;
}
section {
background:red;
height: 100vh;
}
.dark-bg {
background: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu__list pull-md-right">
<li class="menu__item menu__item--current">
<a class="menu__link" data-target="intro-fabio">home</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="about-fabio">about</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="skills-fabio">skills</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="works-fabio">works</a>
</li>
<li class="menu__item">
<a class="menu__link" data-target="contacts-fabio">contacts</a>
</li>
</ul>
<!-- HOME
======================================================== -->
<section id="intro-fabio">
</section>
<!-- ABOUT
======================================================== -->
<section id="about-fabio" class="dark-bg">
</section>
<!-- SKILLS
======================================================== -->
<section id="skills-fabio">
</section>
<!-- WORKS
======================================================== -->
<section id="works-fabio" class="dark-bg">
</section>
<!-- CONTACTS
======================================================== -->
<section id="contacts-fabio">
</section>