I have a navbar with an unordered list with structure of <a></a>
tag inside the <li></li>.
This is what it looks like:
document.querySelector('.nav-links').addEventListener('click', function(e) {
console.log(e.target);
e.preventDefault();
if (e.target.classList.contains('nav-link')) {
const id = e.target.getAttribute('href');
console.log(id);
document.querySelector(id).scrollIntoView({
behavior: 'smooth'
});
}
});
<ul class="nav-links">
<li class="nav-item">
<a href="#section-1" class="nav-link">Home</a>
</li>
<li class="nav-item">
<a href="#section-2" class="nav-link">Products</a>
</li>
<li class="nav-item">
<a href="#section-3" class="nav-link">Benefits</a>
</li>
<li class="nav-item">
<a href="#section-4" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="#section-5" class="nav-link">Contact</a>
</li>
</ul>
I can access the tag directly even if i clicked the outside of the link like in the screenshot below:
but the problem is that i need the value on the href
so i can still change the view of my website when the
CodePudding user response:
Instead of binding the click event to ul
you can bind that to li
.
function onLinkClicked(e) {
e.preventDefault();
if (e.target.classList.contains('nav-link')) {
const id = e.target.getAttribute('href');
document.querySelector(id).scrollIntoView({ behavior: 'smooth' });
}
}
Array.from(document.querySelectorAll('.nav-item'))
.forEach((node) => node.addEventListener('click', onLinkClicked))
.box {
width: 100%;
height: 200px;
margin: 5px;
background: yellow;
}
<ul class="nav-links">
<li class="nav-item">
<a href="#section-1" class="nav-link">Home</a>
</li>
<li class="nav-item">
<a href="#section-2" class="nav-link">Products</a>
</li>
<li class="nav-item">
<a href="#section-3" class="nav-link">Benefits</a>
</li>
<li class="nav-item">
<a href="#section-4" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="#section-5" class="nav-link">Contact</a>
</li>
</ul>
<div class="box" id="section-1">Home Section</div>
<div class="box" id="section-2">Products Section</div>
<div class="box" id="section-3">Benefits Section</div>
<div class="box" id="section-4">About Section</div>
<div class="box" id="section-5">Contact Section</div>
CodePudding user response:
You can check if the element clicked was the link, otherwise find it:
document.querySelector('.nav-links').addEventListener('click', function(e) {
console.log(e.target);
e.preventDefault();
const link = e.target.classList.contains('nav-link') ? e.target : e.target.querySelector('a');
const id = link.getAttribute('href');
console.log(id);
document.querySelector(id)?.scrollIntoView({
behavior: 'smooth'
});
});
.box::before { content: attr(id); }
.box {
background-color: #f0f0f0;
height: 50vh;
margin: 5px;
}
<ul class="nav-links">
<li class="nav-item">
<a href="#section-1" class="nav-link">Home</a>
</li>
<li class="nav-item">
<a href="#section-2" class="nav-link">Products</a>
</li>
<li class="nav-item">
<a href="#section-3" class="nav-link">Benefits</a>
</li>
<li class="nav-item">
<a href="#section-4" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="#section-5" class="nav-link">Contact</a>
</li>
</ul>
<div class="box" id="section-1"></div>
<div class="box" id="section-2"></div>
<div class="box" id="section-3"></div>
<div class="box" id="section-4"></div>
<div class="box" id="section-5"></div>