What steps should I follow to build a single page application with a navigation bar?

For my latest project, I am working on a single page application that features a dynamic navbar. The purpose of this application is for a music review site where genres like 'Pop', 'HipHop' and 'Jazz' will be showcased in the navbar. Instead of having separate HTML pages for each genre, I want to consolidate everything into one large HTML page.


Although I have the JavaScript code ready to make this happen, I need guidance on how to adjust the navbar content accordingly.

This is the snippet of my javascript file and nav bar:

I would greatly appreciate any assistance

    pages: [],
    show: new Event('show'),
    init: function(){
        app.pages = document.querySelectorAll('.page');
        app.pages.forEach((pg)=>{
            pg.addEventListener('show', app.pageShown);
        })

        document.querySelectorAll('.nav-link').forEach((link)=>{
            link.addEventListener('click', app.nav);
        })
        history.replaceState({}, 'Home', '#home');
        window.addEventListener('popstate', app.poppin);
    },
    nav: function(ev){
        ev.preventDefault();
        let currentPage = ev.target.getAttribute('data-target');
        document.querySelector('.active').classList.remove('active');
        document.getElementById(currentPage).classList.add('active');
        console.log(currentPage)
        history.pushState({}, currentPage, `#${currentPage}`);
        document.getElementById(currentPage).dispatchEvent(app.show);
    },
    pageShown: function(ev){
        console.log('Page', ev.target.id, 'just shown');
        let h1 = ev.target.querySelector('h1');
        h1.classList.add('big')
        setTimeout((h)=>{
            h.classList.remove('big');
        }, 1200, h1);
    },
    poppin: function(ev){
        console.log(location.hash, 'popstate event');
        let hash = location.hash.replace('#' ,'');
        document.querySelector('.active').classList.remove('active');
        document.getElementById(hash).classList.add('active');
        console.log(hash)
        //history.pushState({}, currentPage, `#${currentPage}`);
        document.getElementById(hash).dispatchEvent(app.show);
    }
}

document.addEventListener('DOMContentLoaded', app.init);

NAVBAR: 

    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="statichtmlpage.html">Home</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
            <div class="navbar-nav">
                <a class="nav-item nav-link" href="pop.html">pop</a>
                <a class="nav-item nav-link" href="hiphop.html">hiphop</a>
                <a class="nav-item nav-link" href="jazz.html">jazz</a>
                <a class="nav-item nav-link" href="#">Absolute trash</a>

Answer №1

Utilizing a combination of resources, primarily sourced from https://www.w3schools.com/howto/howto_js_tabs.asp
This solution aligns closely with your inquiry. Feel free to confirm if it addresses your issue.
For a more advanced approach, I recommend exploring VueJS framework (https://vuejs.org/). It offers additional functionalities to enhance your application. If server-side rendering is of interest, consider delving into NuxtJS (https://nuxtjs.org/guide).

function adjustStyle(categoryName) {
  var i, contentTab, linksTab;
  contentTab = document.getElementsByClassName("tabcontent");
  for (i = 0; i < contentTab.length; i++) {
    contentTab[i].style.display = "none";
  }
  linksTab = document.getElementsByClassName("tablinks");
  for (i = 0; i < linksTab.length; i++) {
    linksTab[i].className = linksTab[i].className.replace(" active", "");
  }
  document.getElementById(categoryName).style.display = "block";
  return linksTab
}

function selectTab(event, categoryName) {
  adjustStyle(categoryName)
  event.currentTarget.className += " active";
}

function tabSelection(categoryName) {
  var linksTab = adjustStyle(categoryName)
  for (i = 0; i < linksTab.length; i++) {
    if (linksTab[i].innerHTML == categoryName) {
      linksTab[i].className += " active"
    }
  }
}
/* Customize the tab */

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}


/* Design the buttons inside the tab */

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}


/* Modify background color of buttons when hovered */

.tab button:hover {
  background-color: #ddd;
}


/* Create an active/current tablink class */

.tab button.active {
  background-color: #ccc;
}


/* Style the tab content */

.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 0px solid #ccc;
  border-top: none;
}

#Popular {
  display: block
}
<div class="tab">
  <button class="tablinks active" onclick="selectTab(event, 'Popular')">Popular</button>
  <button class="tablinks" onclick="selectTab(event, 'Rock')">Rock</button>
  <button class="tablinks" onclick="selectTab(event, 'Blues')">Blues</button>
</div>

<div id="Popular" class="tabcontent">
  <h3>Popular</h3>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus ut massa et ullamcorper. In hac habitasse platea dictumst. Quisque tempor odio sit amet aliquam iaculis.</p>
  <p>Click <a href="#!" onclick="tabSelection('Blues')">HERE</a> if you're feeling Bluesy.</p>
</div>

<div id="Rock" class="tabcontent">
  <h3>Rock</h3>
  <p>Sed eu efficitur lorem. Pellentesque varius nulla nec lectus consectetur ullamcorper. In at urna orci. Sed ut malesuada elit, vel tempor leo.</p>
</div>

<div id="Blues" class="tabcontent">
  <h3>Blues</h3>
  <p>Fusce arcu magna, mollis eu cursus ut, mollis sit amet quam. Aenean mattis turpis vitae iaculis venenatis. Cras tempus gravida quam in malesuada.</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

What's the best way to implement a conditional header in React?

I am looking to create a conditional display of the Header based on different pages. Specifically, I want the Header to be hidden on the Home page and shown on other pages like posts page, projects page, etc. I have been brainstorming possible solutions f ...

Navigating to a URL in the active tab using the Firefox WebExtension API

Embarking on the journey of creating a Firefox web extension/add-on has been an exciting experience for me. However, I am facing some challenges when it comes to navigating to a URL in the active tab. I have tried using document.open('https://www.gith ...

What is the most efficient method for managing the save form process (insertion vs updating) using AJAX?

I have been exploring various methods to manage the insert and update processes in my front-end forms efficiently. There are two distinct scenarios that I need to address: one where users input new data and save that record, and another where they update a ...

Execute a php script at a frequency of every 10 seconds

Looking for some assistance with my code. I am trying to make use of setInterval in order to run the PHP script update.php every 10 seconds and refresh the div with an id of verification. However, it seems like setInterval is causing issues with the func ...

Troubleshooting NPM installation failures with SQLite build

After updating to macOS Mojave and installing the latest versions of node 12.1.0, npm 6.9.0, brew 2.1.1, and Python 2.7.10 on darwin, I encountered an issue while running npm install in a package.json file for a project that includes "sqlite3": "4.0.6". ...

Struggling with integrating jQuery append into Backbone.js

Having trouble using jQuery.append() and backbonejs. Currently, when attempting to append, nothing happens (except the jQuery object is returned in the immediate window) and the count remains at 0. Manually adding the element has not been successful. I als ...

Retrieve information from the third section by utilizing ajax

My current setup involves: Having a form in form.php for inserting data, Displaying data in table format with pagination on display.php, and Using validation.js for validating form data along with the following function: $('#pagiCount a'). ...

Display a div beside it when hovering over a specific part of the image

If I have an image that is 200px wide and 900px tall How can I make a div display alongside it when hovering over a specific section of the image? ...

How can I apply multiple backgrounds to a SVG object?

I am in the process of converting an HTML element into an SVG object. I have made progress, but there is one thing that I am stuck on: I'm having trouble figuring out how to define multiple backgrounds in SVG, specifically when it comes to converting ...

converting HTML values to TypeScript

I'm a beginner with Angular and could use some assistance. Currently, I have two components - one for the index and another for navigation. Within the index component, there are subcomponents that change based on the value of a variable called produ ...

Can anyone recommend any JavaScript or jQuery thumbnail scripts that are similar to TimThimb (PHP)?

TimThumb is a versatile tool that can quickly generate thumbnails from images of any size or dimensions to fit any desired size. It has the ability to resize, crop, or zoom crop images without any hassle. I've been on the lookout for JavaScript alter ...

Utilizing a function within the App.js file located in the public folder using React JS

I need to execute a function called callMe that is defined in src/App.js from the public folder. In App.js import messaging from './firebase-init'; import './App.css'; function App () { function callMe() { console.log('Call m ...

In HTML, a Bootstrap row appears on top of another row when viewing on mobile devices

I have implemented a Bootstrap HTML section that consists of a container and two main rows. Here is the code snippet: <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"> <style& ...

The Google Apps Script will activate only on weekdays between the hours of 10 AM and 5 PM, running every hour

function Purchase() { var ss=SpreadsheetApp.getActive(); var sheet=ss.getSheetByName("Buy"); var Cvalues=sheet.getRange(2,3,sheet.getLastRow()-1,1).getValues(); var Avalues=sheet.getRange(2,1,sheet.getLastRow()-1,1).getValues(); var r ...

Having trouble connecting Heroku to my asset javascript and css files within my Rails application

After deploying my app on Heroku, I encountered an issue where my scripts and CSS files are not properly linked. While everything works fine locally, the same does not hold true in the production environment. This is how I am rendering my scripts and CSS ...

From turning strings into integers to numerical transformations

I need help converting the string "9876543210223023" into an integer without changing its value. I've tried using parseInt, but it always converts to 9876543210223024 which is causing issues with my validations. Can someone suggest a method to keep th ...

Is it feasible to utilize a prop for styling in Vue using SCSS/SASS?

I am currently working on enabling custom theming for my component that utilizes bootstrap. I am aiming to define its $primary tag in SCSS within the section of the Vue component. Currently, my styling setup looks like this: <style scoped lang="scss"& ...

The power of PHP's echo function comes alive as it seamlessly connects

I am currently working on developing a product catalog using PHP. Below is the HTML flex-container code: <div class="products"> <?php echo file_get_contents("http://192.168.64.2/CodeWay/Pages/product.php"); ?> & ...

The webview is failing to display the dropdown menu

Everything seems to be working fine with the 3 dropdown menus on this website, as they appear on top of the images below them. However, when I convert the site into an Android app using Webview, the menus end up going under the images instead of on top. ...

The value 'true' was returned for an attribute 'exact' that is not of boolean type

How can I resolve this warning? Sample Code const Main = (header, navigation) => { return ( <> <div> {navigation !== false && <Navigation />} </div> </> ) } I attempted this soluti ...