Home > Software engineering >  Highlighting active anchor link
Highlighting active anchor link

Time:04-26

I have a menu in my sidebar that contains anchor links like so:

<ul>
<li><a href="#anchor1">Link 1</a></li>
<li><a href="#anchor2">Link 2</a></li>
<li><a href="#anchor3">Link 3</a></li>
</ul>

Now I need to highlight the active li in bold, so that when the user has the anchor link in view (for example by scrolling down the page or by having the link clicked), it is bold. How can I achieve this?

EDIT to clarify: my html to display the links is:

<div anchor1">
<h2>Link 1</h2>
<p>Some text...</p>
</div>
<div anchor2">
<h2>Link 2</h2>
<p>Some text...</p>
</div>
<div anchor3">
<h2>Link 3</h2>
<p>Some text...</p>
</div>

CodePudding user response:

Here I am using the Intersection_Observer_API

We need to tweak the margin to only have one link active when bits of the previous content is in the viewport

let dir = 0
window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  dir = this.oldScroll > this.scrollY ? 1 : -1;
  this.oldScroll = this.scrollY;
}

const divs = document.querySelectorAll('.content');
let callback = (entries, observer) => {
  entries.forEach(entry => {
    const targetDiv = document.querySelector(`[href="#${entry.target.id}"]`);
    if (entry.isIntersecting) targetDiv.classList.add('active')
    const active = [...document.querySelectorAll('.active')];
    if (active.length > 1) active[dir === 1 ? 1 : 0].classList.remove("active")
  });
};

const observer = new IntersectionObserver(callback);
divs.forEach(div => observer.observe(div));
.content {
  height: 700px;
  border: 1px solid black;
  margin-bottom: 50px
}
.active {
 font-weight: bold;
}
<ul style="position: fixed">
  <li><a href="#anchor1">Link 1</a></li>
  <li><a href="#anchor2">Link 2</a></li>
  <li><a href="#anchor3">Link 3</a></li>
</ul>
<div style="height:500px; overflow auto">
  <div  id="anchor1">Anchor 1</div>
  <div  id="anchor2">Anchor 2</div>
  <div  id="anchor3">Anchor 3</div>
</div>

CodePudding user response:

If you have an .active class applied to the current li, use font-weight:bold

.active{
  font-weight:bold;
}
<ul>
  <li><a href="#anchor1">Link 1</a></li>
  <li ><a href="#anchor2">Link 2</a></li>
  <li><a href="#anchor3">Link 3</a></li>
</ul>

CodePudding user response:

Here the demo for has you want.

$(".menu li a").click(function() {
    $('li a').not(this).removeClass('active');
    $(this).toggleClass('active');
});

$(document).ready(function(){
    var link1 = $('#home').offset().top;
    var link2 = $('#about').offset().top;
    var link3 = $('#contact').offset().top;
    

    
    $(window).scroll(function() {
      
        var winTop = $(window).scrollTop();
        if(winTop >= link1 && winTop < link2){
            $('.home').addClass("active");
        }
        else if(winTop >= link2 && winTop < link3){
            $('.about').addClass("active");
            $('.home').removeClass("active");
        } 
        else if(winTop >= link3){
            $('.about').removeClass("active");
            $('.contact').addClass("active");
        }else{
            $('a').removeClass("active");
        }
    });
});
a.active{
  font-weight:bold;
}
html{
  scroll-behavior: smooth;
}
.menu{
  postion:relative;
}
.menu ul{
  position:fixed;
  top:0px;
}
div{
  padding-top:100px;
}
#contact{
  padding-bottom:100px;
}
<html>

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<div >
  <ul>
    <li><a href="#home" >Link 1</a></li>
    <li><a href="#about" >Link 2</a></li>
    <li><a href="#contact" >Link 3</a></li>
  </ul>
</div>

<div id="home">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>

<div id="about">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>

<div id="contact">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
</html>

  • Related