Making a transparent bootstrap navbar solid on scroll - javascript

I am currently working on a sticky bootstrap navbar that is transparent, but on scroll becomes a solid color so it is visibile. The code seems to be working on the desktop view and fades in and out correctly from transparent to solid. The problem I am having is that for some reason the hamburger menu drop down continues to be transparent and is not taking the background color property.
const [navbar, setNavbar] = useState(false)
const changeBackground = () => {
if (window.scrollY >= 75) {
setNavbar(true)
} else {
setNavbar(false)
}
}
window.addEventListener('scroll', changeBackground)
<nav id="home" className={navbar ? 'navbar active navbar-expand-lg fixed-top' : 'navbar navbar-expand-lg fixed-top'}>
<div className="container-fluid">
<Link className="navbar-brand"><img className="logo" src={logo} /></Link>
<button className="navbar-toggler no-border" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<FontAwesomeIcon/>
</button>
</div>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav active navBarFormat mb-2 mb-lg-0">
<li className="nav-item">
<Link
to="about"
className="nav-link ">about</Link>
</li>
</ul>
</div>
</nav>

Related

Navbar state - manually change from normal state to collapsed state

I have the following navbar:
<nav class="navbar fixed-top navbar-expand-sm navbar-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto ">
<li class="nav-item">
<a class="nav-link link-light active" href="#a">A</a>
</li>
<li class="nav-item">
<a class="nav-link link-light" href="#b">B</a>
</li>
<li class="nav-item">
<a class="nav-link link-light" href="#c">C</a>
</li>
</ul>
</div>
</div>
</nav>
What I'm trying to do is that in case the display resolution is big enough for it to appear as not collapsed, then if the user's scroll Y isn't on top, the navbar will appear as collapsed (no matter the display size), this is what i'm trying using js, but it's not working and i wasn't successful in finding something helpful on how to control the actual navbar state (collapsed\not collapsed)...appreciate any help.
let navcollapse = document.getElementById('navbarSupportedContent')
window.addEventListener('scroll', (e) => {
if(window.scrollY == 0) { // top position
// open the navbar
} else {
navcollapse.collapse = 'hide'; // collapse it
}
});
-if display is small for it to be collapsed by default then nothing changes and navbar will remain in collapsed state no matter if scroll Y is on top or not.
Just when the idea of changing the Sass file grid-breakpoints came to mind, I stumbled on a bootstrap break point that I wasn't familiar with... the 'XS', which will collapse the navbar on big screens since it'll do that for dimensions bigger than or equal to 576px (while the 'SM' break point takes effect on dimensions smaller than 576px so if the screen is small enough, the navbar will stay collapsed either way as requested).
Anyways, this is the code for collapsing the navbar (added an ID for the nav element in html file, the js code):
JS code:
window.addEventListener('scroll', function() {
if (window.scrollY == 0) { // top position - expand navbar
document.getElementById('navbarscroll-spy').classList.remove('navbar-expand-xs');
document.getElementById('navbarscroll-spy').classList.add('navbar-expand-sm');
} else { // scrolled - collapse navbar
document.getElementById('navbarscroll-spy').classList.remove('navbar-expand-sm');
document.getElementById('navbarscroll-spy').classList.add('navbar-expand-xs');
}
}
html:
<nav id="navbarscroll-spy" class="navbar fixed-top navbar-expand-sm navbar-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto ">
<li class="nav-item">
<a class="nav-link link-light active" href="#a">A</a>
</li>
<li class="nav-item">
<a class="nav-link link-light" href="#b">B</a>
</li>
<li class="nav-item">
<a class="nav-link link-light" href="#c">C</a>
</li>
</ul>
</div>
</div>
</nav>

Collapsed Navbar not working react and bootstrap 5

For some reason the collapsed navbar icon does not expand when clicked on on smaller screens. I copied the example from bootstrap 5 and made sure to include bootstrap css/js and jquery.
class NavBar extends Component {
render() {
return (
<div className="NavBar">
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav mx-auto">
<HashLink className="navbar-brand" to="/#app">
Site
</HashLink>
<HashLink className="nav-link" to="/#about">
About
</HashLink>
<HashLink className="nav-link" to="/#skills">
Skills
</HashLink>
<HashLink className="nav-link" to="/#experience">
Experience
</HashLink>
<Link className="nav-link" to="/calculator">
Calculator
</Link>
</div>
</div>
</div>
</nav>
</div>
);
}
}
The problem is we didn't add the bootstrap js file
so, add this in App.js file
import 'bootstrap/dist/js/bootstrap.bundle';
I found an answer here that works via react hooks: https://dev.to/johnotu/how-to-toggle-bootstrap-navbar-collapse-button-in-react-without-jquery-joo
import React, { useState } from 'react';
import Logo from '../images/logo_512x512.png';
const TopNav = props => {
const [isNavCollapsed, setIsNavCollapsed] = useState(true);
const handleNavCollapse = () => setIsNavCollapsed(!isNavCollapsed);
return (
<nav class="navbar navbar-expand-lg navbar-light bg-light rounded">
<a class="navbar-brand text-info font-weight-bolder" href="/">
<img src={Logo} alt="Logo" width="36" height="36" className="vertical-align-middle" />
<span className="">Discounter</span>
</a>
<button class="custom-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded={!isNavCollapsed ? true : false} aria-label="Toggle navigation" onClick={handleNavCollapse}>
<span class="navbar-toggler-icon"></span>
</button>
<div class={`${isNavCollapsed ? 'collapse' : ''} navbar-collapse`} id="navbarsExample09">
<a className="nav-link text-info" href="/contact">Support</a>
<a className="nav-link text-info" href="/login">Login</a>
<a href="/request-demo" className="btn btn-sm btn-info nav-link text-white" >Request demo</a>
</div>
</nav>
);
}
export default TopNav;
I was having the same issues, i fixed them by adding -bs to data-toggle & data-target. thus turning them to data-bs-toggle & data-bs-target respectively.
Here are my package.json dependencies:
"bootstrap": "^5.2.0",
"jquery": "^3.6.0",
"popper.js":
"^1.16.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Example code:
Changed from
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
Changed to:
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
you must have to import this.
import 'bootstrap/dist/js/bootstrap.bundle';
<nav class="navbar navbar-expand-lg navbar-light bg-light">
Navbar
Home
Link
Dropdown
Action
Another action
Something else here
Disabled
Search

how to change color of navbar when scrolling to bottom?

I have 2 probelems.
Problem-1: I am trying changing navbar background color when scrolling to bottom. I am trying to add the class but it couldn't override the bootstrap !important attribute. but I have override it using this line:
nav.scrolled {
background-color: #e8e4e1 !important;
box-shadow: 2px 10px 4px var(--section-bg-light);
}
problem-2: how to change navbar background with javascript while scrolling to the bottom of the page, footer of the page?
let navbar = document.querySelector('.navbar');
let section = document.querySelectorAll('section');
section.addEventListener('mouseover', addIt);
function addIt() {
navbar.classList.remove('bg-transparent');
navbar.classList.add('bg-dark');
}
nav.bg-dark {
background-color: #e8e4e1 !important;
}
<nav class="navbar navbar-expand-lg navbar-light bg-transparent fixed-top">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img src="./img/logo-min.png" alt="JN-Fashion-Zone"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item home">
<a class="nav-link" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Services</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contacts</a>
</li>
</ul>
</div>
</div>
</nav>
Please check out How to override !important?
You need to use high specificity to override the !important rule.
Try adding more levels to your selector.
var nav = document.querySelector('nav');
window.addEventListener('scroll', function () {
if (window.pageYOffset > 100) {
nav.classList.add('bg-info', 'shadow');
} else {
nav.classList.remove('bg-info', 'shadow');
}
});

React.js Navbar Hamburger Menu won't toggle closed

So, I have a react.js app built with a group. Our Navbar works, but when the Navbar is toggled from a smaller screen using the Hamburger menu, it will open, but the toggle doesn't work to close it, it stays stuck open. I didn't program this page, but I've been trying to debug why it won't close, and for what I can see, it should work.
Yes, I know react.bootstrap is a thing, and I was thinking about converting it, but I'm on a deadline and don't want to rewrite this entire component from scratch if it is at all possible. Any thoughts, or suggestions. I thought it was likely in the toggleNav function, but from what I've tested it seems to be correct.
import React, { Component } from "react";
import { Link } from "react-router-dom";
import "./style.css";
class Nav extends Component {
state = {
open: false,
width: window.innerWidth,
};
updateWidth = () => {
const newState = { width: window.innerWidth };
if (this.state.open && newState.width > 991) {
newState.open = false;
}
this.setState(newState);
};
toggleNav = () => {
this.setState({ open: !this.state.open });
};
setActiveNavItem = (path) => {
return window.location.pathname === path ? "nav-link active" : "nav-link";
};
componentDidMount() {
window.addEventListener("resize", this.updateWidth);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWidth);
}
render() {
return (
<nav className="navbar navbar-expand-lg navbar-light">
<Link className="navbar-brand" to="/">
Seenit
</Link>
<button
onClick={this.toggleNav}
className="navbar-toggler"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div
className={`${this.state.open ? "" : "collapse "}navbar-collapse`}
id="navbarNav"
>
{/* Navbar items */}
<ul className="navbar-nav">
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/")}
to="/"
>
Home
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/create-post")}
to="/create-post"
>
Create a Post
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/log-in")}
to="/log-in"
>
Log In
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/sign-up")}
to="/sign-up"
>
Sign Up
</Link>
</li>
</ul>
</div>
</nav>
);
}
}
export default Nav;
This React component is a direct implementation of the Bootstrap Toggler Navbar.
Unfortunately, this component also contains code that modifies the navbar, which almost certainly breaks the Bootstrap code that controls collapsible navbars.
Here is the pure HTML version of this navbar component. Note that it collapses to a hamburger on narrow screens (as desired).
It should be straightforward to remove from this component the code that modifies the Bootstrap Toggler navbar.
.navbar {
outline: 1px solid #ddd;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<body class="p-2">
<nav class="navbar navbar-expand-lg navbar-light mr-5">
<a class="navbar-brand" href="#">Seenit</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Create a Post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Log In</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Sign Up</a>
</li>
</ul>
</div>
</nav>
<!-- JS required for Bootstrap -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>

Bootstrap 4 navbar - collapse on nav-link click in vanilla JS

I am trying to make the Bootstrap 4 navbar only use vanilla js vs any jQuery. So far I've been able to get the toggler to trigger the nav to collapse and close on mobile. What I am now trying to figure out is how to make the navbar collapse when you click on a "nav-link"
Here is my HTML for the nav:
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-lg p-3 mb-5 bg-white fixed-top">
<div class="container">
<a class="navbar-brand" href="#">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive"
aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item" >
<a class="nav-link" href="#about">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Browse Menu</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#visit">Contact</a>
</li>
</ul>
</div>
</div>
And my JS for the collapsing
(function () {
"use strict";
document.querySelectorAll("button.navbar-toggler")[0].addEventListener("click", function (event) {
var target = this.getAttribute("data-target");
var subbar = document.querySelectorAll(target)[0];
subbar.className = (subbar.className + " show").replace(/ show show/, "");
});
})();
But how do I make it so when a user clicks a <a class="nav-link" href="#"></a> it'll also collapse the navbar?
Thanks!
Since you are using custom code, it's unnecessary to have the target (data-target="#navbarResponsive") on the html. So we can rewrite the click handler to handle both elements, the toggler and the links. To toggle a class just use the method toggle on classList.
document.addEventListener("click", function(event) {
if (event.target.classList.contains("navbar-toggler-icon")) {
document.getElementById("navbarResponsive").classList.toggle("show");
} else if (event.target.classList.contains("nav-link")) {
document.getElementById("navbarResponsive").classList.remove("show");
}
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-lg p-3 mb-5 bg-white fixed-top">
<div class="container">
<a class="navbar-brand" href="#">Start Bootstrap</a>
<button class="navbar-toggler" type="button" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item"><a class="nav-link" href="#about">About Us</a></li>
<li class="nav-item"><a class="nav-link" href="#">Browse Menu</a> </li>
<li class="nav-item"> <a class="nav-link" href="#visit">Contact</a> </li>
</ul>
</div>
</div>
</nav>
A possible solution for your question is to find all the .nav-links and add a click listener to remove the show class from the class list.
Also, you could simplify a bit your code using Element.classList.toggle(), something like:
(function() {
let subbar = document.getElementById("navbarResponsive");
document
.querySelectorAll("button.navbar-toggler")[0]
.addEventListener("click", function(event) {
subbar.classList.toggle("show");
});
for (let navItem of document.querySelectorAll("a.nav-link")) {
navItem.addEventListener("click", function(event) {
subbar.classList.remove("show");
});
}
})();
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-lg p-3 mb-5 bg-white fixed-top">
<div class="container">
<a class="navbar-brand" href="#">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="#about">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Browse Menu</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#visit">Contact</a>
</li>
</ul>
</div>
</div>
</nav>

Categories