Arranging titles on the top of the page in a column format, resembling an index

Has anyone figured out how to make the title of the content stick at the top, one below the other, as the user scrolls? I've been using Bootstrap's Scrollspy, which works fine, but I need a few additional features. You can check out the codepen link here. (I didn't include the code in the SO editor because it shows a mobile view.)

  1. Currently, there are 2 titles displayed on the screen - one inside the Navbar and the other within the content.
  2. The titles should stick one below the other, resembling an index of the page.
  3. When a user clicks on any of the titles, the page should smoothly scroll to that specific content (I know this is achievable with Scrollspy, but only the title with the .active class is highlighted).

I understand that writing custom JS for this may take some time (which I would prefer not to do). I've tried searching online, but most plugins available are similar to Scrollspy.

I'm open to using any plugin that offers this feature, or even simple modifications to the existing Scrollspy would be fine with me.

https://i.sstatic.net/91fq0.png

Answer №1

I believe this is the information you are seeking. Please inform me if you require any additional modifications.

$(document).ready(function() {
  var navHeight, activeLiCount, activeLiHeight;
  $(document).on("scroll", onScroll);

  function onScroll(event) {
    var previousScrollTop = 0,
      scrollLock = false,
      scrollPos = $(document).scrollTop() + $(".nav").height();
    $(".nav a").each(function() {
      var currLink = $(this),
        refElement = $(currLink.attr("href"));
      if (refElement.position().top <= scrollPos) {
        currLink.parent("li").addClass("active");
        if (scrollLock) {
          $(window).scrollTop(previousScrollTop);
        }
        previousScrollTop = $(window).scrollTop();
      } else {
        currLink.parent("li").removeClass("active");
      }
    });
  }

  $("#header a").click(function() {
    var pageId = $(this).attr("href");
    $(".nav li").removeClass("active");
    $(this).parent("li").addClass("active");
    activeLiCount = $(this).parent("li").index();
    activeLiHeight = $(".nav li.active").height();
    navHeight = activeLiCount * activeLiHeight;
    $("html, body").animate({
      scrollTop: $(pageId).offset().top - navHeight
    }, 500);
    return false;
  });
});
* {
  margin: 0;
  padding: 0;
  font-family: arial;
}

#header {
  background: #000;
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

ul.nav>li {
  list-style: none;
  display: none;
}

.nav>li>a {
  color: #000;
  text-decoration: none;
  padding: 10px;
  display: block;
  font-size: 16px;
  border-bottom: 1px solid #999;
}

.nav li.active,
.nav a:hover {
  background: #fff;
  color: #000;
}

.nav li.active {
  display: block;
}

.section h3 {
  padding: 12px 0;
  margin: 0 0 10px 0;
  font-size: 16px;
  font-weight: normal;
  border-bottom: 1px solid #999;
}

p {
  margin: 10px 0 0 0;
}

.section {
  min-height: 100vh;
  padding: 0 15px;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />

<div id="header">
  <ul class="nav">
    <li class="active"><a href="#page1">Page One</a></li>
    <li><a href="#page2">Page Two</a></li>
    <li><a href="#page3">Page Three</a></li>
    <li><a href="#page4">Page Four</a></li>
    <li><a href="#page5">Page Five</a></li>
  </ul>
</div>
<div id="page1" class="section">
  <h3>Page one</h3>
  <p>Donec id ipsum odio. Cras accumsan consectetur nibh, vitae pretium dui hendrerit sed. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ac orci elit. Nunc faucibus eros vulputate purus aliquam vel blandit ligula
    pharetra.
  </p>
  <p>Donec id ipsum odio. Cras accumsan consectetur nibh, vitae pretium dui hendrerit sed. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ac orci elit. Nunc faucibus eros vulputate purus aliquam vel blandit ligula
    pharetra.
  </p>
 ···
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using JavaScript and Tampermonkey to convert strings from an HTML element into an array

I am trying to change the names of months into numbers and place them in a table cell on a website. I thought using an array would make it easier to reference the month names by their corresponding array numbers, allowing me to add table tags before and af ...

Is there a way for me to configure my website so that when a link is clicked, my PDF file will automatically open in Adobe

I've been facing an issue where I need my users to access a specific PDF file from a link on my website. Currently, the PDF opens in a separate tab next to my site, but ideally, I would like it to be forced to open in Adobe Reader directly. Is this ac ...

Understanding the Process of Accessing Array Values in Immutable.js

I'm feeling a little puzzled and struggling to figure this out. Let's say I have the following code: const AnObj = Immutable.Map({ a : "a", b : Immutable.List.of( a, b, c, Immutable.Map({ a : "a" }) ) }); When working with Immu ...

Sibling proximity: an excess of elements separating the regulations

Is there a way to make a hidden p element appear when hovering over the first visible element in a tree structure? I found some help on Stack Overflow suggesting the use of adjacent sibling selectors, and while it works well with a simple example, it fails ...

Javascript if-else is malfunctioning

I am having difficulty running the code below which contains if statements. I have tried removing some parts of it, but still can't get the alert to show up. Any advice would be highly appreciated. Thank you. <!DOCTYPE html> &l ...

JavaScript hack for improving slow scrolling experience with smooth scroll on Firefox

As a web application developer, I encountered a particular scenario where there are multiple position:fixed elements, canvases, and an overflow:scroll element. Unfortunately, scrolling in Firefox becomes extremely slow when smooth scrolling is enabled. Wh ...

Creating virtual hover effects on Android browsers for touch events

My Wordpress website is currently utilizing Superfish 1.5.4 to display menu items. The menu on my site includes several main menu items, which are clickable pages, and hovering over these main items should reveal sub-menu options. When I hover over a mai ...

After the form is submitted on the current page, it will not submit again using jquery unless I refresh the page

Currently, I am attempting to submit my form on the same page utilizing jquery. However, after the initial submission, any further attempts fail. It seems that in order for the submission to work properly again, I need to refresh the page first. What cou ...

When an input field is added to an HTML form, all elements positioned below it automatically inherit its attributes

I have a unique combination of HTML and CSS code that creates an impressive login form: <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Prepare to be amazed...</title> <l ...

When using angular's ngHide directive on a button, it will still occupy space in the

At the bottom of this HTML file, there are 3 buttons displayed. The first image illustrates the layout of the 3 buttons. The second image demonstrates what happens when the middle button in the footer is commented out. The third image shows the situat ...

Issues persisting with vertical alignment in table cells on Firefox browser

I've successfully managed to vertically center the contents of .onesizechart in Chrome and Safari, but I'm facing issues with Firefox and IE. Interestingly, the contents of .homepage-sizechart are displaying correctly, leading me to believe that ...

What is the process of comparing one regular expression against another in JavaScript?

I'm looking to check for matches between two regular expressions. To achieve this, I use the .test method on each one. If either of them returns true, I consider them a match. const regexify = (str) => new RegExp( '^' + str ...

Using dots instead of lines for the carousel indicators in PrimeNG

I'm currently working on a carousel feature, but I want to change the indicators from lines to small dots. I know the solution lies within the CSS files, but I'm not sure how to implement it. I think I need to create a new CSS class, but I could ...

Observing data retrieved via ajax in Internet Explorer 9

Is there a way to view data returned by an ajax script in Internet Explorer 9? For instance, Firefox has the Firebug 'All' tab with a 'Response' Sub Tab that displays data returned by an Ajax Script. How can this be done in Internet Ex ...

Angular does not automatically update the template

I've been grappling with this issue for quite some time now and I can't seem to figure out why the angular template is failing to refresh when the scope changes. Here's a link to my JSFiddle - http://jsfiddle.net/HB7LU/2591/ (please note tha ...

How to implement a scrollbar for tables using Angular

How can I implement a vertical scroll bar only for the table body in my Angular code? I want the scroll bar to exclude the header rows. Since all rows are generated by ng-repeat, I am unsure how to add overflow style specifically for the table body. Here ...

This code snippet results in the property being unrecognized

I recently wrote this block of code and encountered an error while trying to run the alert function. It keeps telling me that 'this.words' is not defined. I suspect the issue lies within the jQuery portion, as I am able to access the array where ...

Can anyone explain to me how to render attributes of a tag in Vue? I'm curious about how v-for interacts with HTML

<ul> <span class="tabs" :class="{ activeTab: selectedTab === tab }" v-for="(tab, index) in tabs" @click="selectedTab = tab" :key="tab"> {{ in ...

Remove webpack functions from the bundle

After following a comprehensive tutorial on bundling files with webpack and some additional online research, I successfully created a configuration file that organizes the modules in my library into the specified structure: dist/node/weather.min.js dist/we ...

The click event will not be triggered if the element is removed by my blur event

My dropdown list is dynamic, with clickable items that trigger actions when clicked. Upon focus, the list displays suggested items When blurred, the list clears its contents The issue arises when blur/focusout events are triggered, causing my element to ...