I have made a one-page website using HTML, CSS/Tailwind, and Vanilla JavaScript. The issue is that when I click on one of the navbar links sometimes it works, and sometimes it gets stuck; where it does not respond until I click multiple times on the link(The number of times is not consistent). Not sure what the issue could be.
HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link">
<a onclick="scrollToSection('#main-container')">Hjem</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#services')">Tjenster</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#pricing')">Priser</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#contact')">Kontakt</a>
</li>
</ul>
JavaScript Code:
function scrollToSection(element) {
var element = document.getElementById(element);
element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"})
}
I was able to fix this thanks to the comment made by Rana; where it was pointed out that only the text(a tag) is clickable rather than the entire li element.
New HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link" onclick="scrollToSection('#main-container')">
<a>Hjem</a>
</li>
<li class="nav-link" onclick="scrollToSection('#services')">
<a >Tjenster</a>
</li>
<li class="nav-link" onclick="scrollToSection('#pricing')">
<a >Priser</a>
</li>
<li class="nav-link" onclick="scrollToSection('#contact')">
<a >Kontakt</a>
</li>
</ul>
Related
in my web project, I used a free theme https://themewagon.com/themes/free-bootstrap-4-html-5-admin-dashboard-website-template-skydash/
Here in the nav bar, I customized it as
<nav class="sidebar sidebar-offcanvas" id="sidebar">
<ul class="nav">
<li class="nav-item">
<a class="nav-link elements" href="~/Home/Index">
<i class="icon-grid menu-icon"></i>
<span class="menu-title">Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("Index","SelfService")">
<i class="ti-menu-alt menu-icon"></i>
<span class="menu-title">Our Services</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("OnProcessTasks","SelfCareTasks")">
<i class="ti-timer menu-icon"></i>
<span class="menu-title">In Process Tasks</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("CompletedTasks","SelfCareTasks")">
<i class="ti-file menu-icon"></i>
<span class="menu-title">Completed Tasks</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("OnProcessTasks","SelfCareTasks")">
<i class="ti-face-smile menu-icon"></i>
<span class="menu-title">My Profile</span>
</a>
</li>
</ul>
</nav>
My issue is When I run this, on load first 2 items showed as Active and both items are highlighted. I checked with the sample, but it runs without this issue, also I tried removing the href and then the nav bar showed only one item as active.
I still couldn't figure out why this happening. Any comments?
I can't see what is wrong other than just this thing:
<a class="nav-link elements" href="~/Home/Index">
Change it to:
<a class="nav-link elements" href="#Url.Action("Index", "Home")">
The reason for this change is because you're following the Razor Syntax.
I am in the process of porting an old web form app to Blazor WASM.
The app is using a lot of JavaScript and I wonder how to best work with the DOM in Blazor.
Let's take this example:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" data-tabIndex="0" href="#">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="1" href="#">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="2" href="#">Gebyrer</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="3" href="#">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="4" href="#">Praktiske oplysninger</a>
</li>
</ul>
We need the following to have a functional tab strip
A click handler that gets the tab clicked
Code that sets the Active class on the clicked tab and removed it on the previous tab.
I can easily add an onclick handler like #onClick="TabClicked(index)" but how can I set the active class and remove the one previously selected?
I know how to do it in JavaScript but now I work in Blazor and would like to use as little js as possible.
This is not the most elegant solution by a long shot but it should help you understand the blazor paradigm better:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="#(myawesometab[0])" data-tabIndex="0" href="#" #onclick="#(e => myawesometabclick(e, 0))">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[1])" data-tabIndex="1" href="#" #onclick="#(e => myawesometabclick(e, 1))">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[2])" data-tabIndex="2" href="#" #onclick="#(e => myawesometabclick(e, 2))">Gebyrer</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[3])" data-tabIndex="3" href="#" #onclick="#(e => myawesometabclick(e, 3))">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[4])" data-tabIndex="4" href="#" #onclick="#(e => myawesometabclick(e, 4))">Praktiske oplysninger</a>
</li>
</ul>
#code
{
private string[] myawesometab = new string[5] { "nav-link active", "nav-link", "nav-link", "nav-link", "nav-link" };
private void myawesometabclick(MouseEventArgs e, int myawesometabnumber)
{
for (int i = 0; i < 5; i++)
{
myawesometab[i] = "nav-link";
}
myawesometab[myawesometabnumber] = "nav-link active";
}
}
Also, as razor pages use a similar file structure to winforms, you might try to update the entire project to razor pages, although I obviously don't understand all the complexities of the project.
I have a navigation which can have up to two sub menus. Means, I have to open the li above (add class "open" to class "arrow") two times if the current page is a href in a sub sub navigation.
However, I am struggling on how to do this, how to solve this problem. My idea was to solve it via jQuery. Is there a better solution?
This is my navigation:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
<span class="selected"></span>
</li>
<li class="nav-item">
Kundenverwaltung
<span class="selected"></span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Example:
The current page is this one: my-domain.com/kundenverwaltung. That means, I have to add the class "active open" to both li elements of the ul sub menus as well as the class "open" to the class "arrow" of the li elements.
This is how it should be:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
</li>
<li class="nav-item">
Kundenverwaltung
</li>
</ul>
</li>
</ul>
</li>
</ul>
I have marked the changes on the classes with ** before and after the class name. This is my jQuery so far:
<script>
$("a.nav-link").each(function(index){
if($(this).attr("href") == window.location.href) {
$(this).parent().addClass("active open");
if ($(this).parent().parent().is("ul")) {
$(this).parent().parent().parent().addClass("active open");
var li = $(this).parent().parent().parent();
$(li[0].nodeName + " .arrow").addClass("open");
}
}
});
</script>
However, I don't think this is the best solution.. is there any better way? Kind regards
If you change the structure of HTML, your code will not be work, so - don't use parent(), try to use closest() https://api.jquery.com/closest, by reason that the closest() is a more reliable method
Cache data. U can use
http://api.jquery.com/attribute-equals-selector:
var $a = jQuery('a[href*="' + window.location.href + '"]');
$a.addClass("active open");
For adding a class to active page you should try added this by backend side, different kind of templating - can do it. But your approach also can be use
I have the following side bar menu code. Upon click on any of the nav items it highlights / makes the class active.
$(document).ready(function() {
$(".nav li").click(function() {
if ($(".nav li").removeClass("active")) {
$(this).removeClass("active");
}
$(this).addClass("active");
});
});
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Now I have similar items at the top of the page presented as a connected circle:
<div class="connected-line">
<ul>
<li class="active">1
<p> System </p>
</li>
<li id="hosts">2
<p> Hosts </p>
</li>
<li>3
<p> Cards </p>
</li>
<li>4
<p> Devices </p>
</li>
</ul>
</div>
See jsfiddle:
https://jsfiddle.net/vk3qw09f/345/
Now if the user clicks on the side bar menu, it should also set corresponding class as active on the "connected-line" list elements.
For eg: Cliking on navbar "System Settings" should also add a class 'active' to the li item inside the circled li "System"
I know it's not recommednded to have the same 2 ids on the same page. So looking for a smarter way to achieve this.
EDIT: my current code will only make that class active: $(this).addClass("active");
I probably want to make all classes that share the same name active
I assume this is what you're looking for.
$(document).ready(function() {
$(".nav li a").click(function(e) {
e.preventDefault();
$(".nav li").removeClass("active");
$(".connected-line li").removeClass("active");
$($(this).attr('href')).addClass('active');
$(this).addClass("active");
});
});
Full working snippet here. Haven't added snippet in answer because:
a) SO doesn't yet support SCSS,
b) i'm lazy.
Also note I made minor mods to your CSS and markup. Another note: duplicate ids are illegal in HTML. You have them? Expect your JavaScript to break. It's as simple as that.
Replace the code in your code. I hope, you can do it. Let me know, If any problem.
$(document).ready(function() {
$(".nav li a").click(function() {
$(".connected-line ul li").removeClass("active");
id = $(this).prop('id');
$("#" + id).addClass("active")
});
});
<div class="connected-line">
<ul>
<li class="active" id="system-settings">1
<p> System </p>
</li>
<li id="hosts">2
<p> Hosts </p>
</li>
<li id="card-range">3
<p> Cards </p>
</li>
<li id="pinpads">4
<p> Devices </p>
</li>
<li id="xmls" >5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
It is best not you have two elements with the same id attribute. This is because native functions such as getElementById will never be able to select the second instance of the element with that id.
That being said to get your demo to work I changed the js to use classes instead of ids on the second set of elements. This can be achieved in many other ways as well:
$(document).ready(function() {
$(".nav li").click(function() {
$('li').removeClass("active");
$(this).removeClass("active");
$(this).addClass("active");
const clickedId = $(this).children()[0].id;
$(`.${clickedId}`).addClass('active');
});
});
and then in the html
<div class="connected-line">
<ul>
<li class="system-settings">1
<p> System </p>
</li>
<li class="hosts">2
<p> Hosts </p>
</li>
<li class="card-range">3
<p> Cards </p>
</li>
<li class="pinpads">4
<p> Devices </p>
</li>
<li class="xmls">5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Rewrite the html code as follows
<div class="connected-line">
<ul>
<li class="system active">1
<p> System </p>
</li>
<li class="host" id="hosts">2
<p> Hosts </p>
</li>
<li class="card">3
<p> Cards </p>
</li>
<li class="device">4
<p> Devices </p>
</li>
<li class="lane">5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item system">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item host">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item card">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item printer">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item pinpad">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Make sure to add same class name to matching li. Then modify the js code as follows,
$(document).ready(function() {
$(".nav li").click(function() {
//Make sure to add class name immediately after "nav-item". For eg."nav-item printer"
var calss=$(this).attr('class').split(' ')[1];
console.log(calss);
$(".nav li").removeClass("active");
$(".connected-line ul li").removeClass("active");
$("li." + calss).addClass("active");
});
});
I'm using a bootstrap template for a side navbar as a partial in EJS which is then included on all pages that use it. Is was taken from their Dashboard template. The HTML is
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="/profile">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accountdetails">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/admin">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/transactions">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contract">Contract</a>
</li>
</ul>
</nav>
Whichever link has the active class has particular styling with darker blue in the background. I now want to change this programatically when navigating to the different links.
They're all going to different pages so I could just change there the issue is that I'm including the whole sidebar code as an EJS partial so that wouldn't work. I also tried this answer but it didn't work (flashes the active styling but disappears - probably because it is routing to another page?).
There are plenty of questions here about changing an HTML element programatically but they usually use document.getElementById which seems like too much work (giving each an ID, checking all, etc). Is there a quicker / correct way of doing this?
You could do the following:
Set a click event on .nav-item, to add .active class.
Remove .active class from any other sibling element.
$('.nav-item').on('click', function() {
$(this).addClass('active').siblings('li').removeClass('active');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item active">
<a class="nav-link" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
Some people answering are a bit confused, thinking you are staying on the same page, and changing the class of your <a> tags. But I think your clicks on these navigate to new pages, and you want the appropriate <a> to have class active when the page loads.
This might help:
<script>
var path = location.pathname; // ex: '/profile';
var activeItem = document.querySelector("a[href='" + path + "']");
activeItem.class += ' active';
</script>
And of course with jquery it's even easier:
$(function() {
var path = location.pathname;
$("a[href='" + path + "']").addClass('active');
})
This is a code for helping you.
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
<script type="text/javascript">
$(function () {
$(".nav-item").click(function () {
$(".nav-item").each(function () {
$(this).find("a").removeClass("active");
});
$(this).find("a").addClass("active");
});
});
</script>
If your using EJS you can probably do something like the following
<a class="nav-link<% if (page_name === 'profile') { %> active<% } %>" href="/profile">Overview</a>
This is untested but should get you going on the right path. Just do a if statement using EJS's syntax to check if you are on the correct page and add the word active.