【问题标题】:How to underline navbar item when it is clicked?单击导航栏项目时如何下划线?
【发布时间】:2020-04-14 08:37:51
【问题描述】:
我有一个导航栏,它突出显示您悬停的菜单项,左 -100 到 0% 效果。我想在单击菜单项时加下划线。我不明白为什么我的 for 循环不能按预期工作。我创建了“x”变量,并认为它会在每次循环迭代时增加 1,但这不会发生,因为当我单击最后一项时,第二个元素被选中。
const menu_links = document.querySelectorAll(".menu-link");
const active = document.querySelectorAll(".link-mark");
for (let i = 0; i < menu_links.length; i += 1) {
var x = 0;
menu_links[i].addEventListener("click", function() {
const current = document.getElementsByClassName("link-active");
current[0].className = current[0].className.replace("link-active", "");
active[x].classList.add("link-active");
})
x += 1;
}
.underline {
position: absolute;
bottom: 0;
height: 5px;
width: 100%;
left: -100%;
background-color: #3399FF;
}
ul li a:hover>.underline {
left: 0%;
transition: 0.4s;
}
.link-active {
position: absolute;
bottom: 0;
height: 5px;
width: 100%;
left: 0%;
background-color: #3399FF;
}
<ul class="menu">
<li>
<a href="#" class="menu-link">
Main Page<div class="link-mark underline link-active"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
Blog<div class="link-mark underline"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
Contact<div class="link-mark underline"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
More<div class="link-mark underline"></div>
</a>
</li>
</ul>
【问题讨论】:
标签:
javascript
html
css
arrays
for-loop
【解决方案1】:
你想做这样的事情吗?
const myMenu = document.getElementById('menu');
myMenu.onclick=e=> // JS event delegation
{
if (e.target.tagName.toLowerCase() != 'a' ) return; // only
e.preventDefault;
let LI = e.target.parentElement;
if (!LI.classList.contains('active'))
{
myMenu.querySelector('li.active').classList.remove('active');
}
LI.classList.add('active');
}
ul#menu {
list-style: none;
}
ul#menu li {
display: inline-block;
padding: .3em .5em;
position:relative;
overflow: hidden;
}
ul#menu li::before {
position: absolute;
display: block;
content: '';
bottom: 0;
left: -100%;
width: 100%;
height: 5px;
transition: 0.4s;
background-color: #3399FF;
}
ul#menu li.active::before,
ul#menu li:hover::before {
left:0%;
}
ul#menu li a {
text-decoration: none;
}
<ul id="menu">
<li class="active"><a href="#">Main Page</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contact</a></li>
<li><a href="#">More</a></li>
</ul>
【解决方案2】:
我不确定是否完全理解你想要什么,但这里有一个 sn-p:
const menu_links = Array.from(document.getElementsByClassName("menu-link"))
function handleClick(evt) {
evt.preventDefault()
menu_links.forEach(link => link.classList.remove("link-active"))
evt.target.classList.add("link-active")
}
menu_links.forEach(link => link.addEventListener("click", handleClick))
.underline {
position: absolute;
bottom: 0;
height: 5px;
width: 0;
left: 0;
background-color: #3399FF;
}
ul li a:hover > .underline {
width: 100%;
transition: width 0.4s;
}
.link-active {
position: absolute;
bottom: 0;
height: 5px;
width: 0;
background-color: #3399FF;
}
<ul class="menu">
<li>
<a href="#" class="menu-link">
Main Page<div class="link-mark underline link-active"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
Blog<div class="link-mark underline"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
Contact<div class="link-mark underline"></div>
</a>
</li>
<li>
<a href="#" class="menu-link">
More<div class="link-mark underline"></div>
</a>
</li>
</ul>
- 我认为与其更改
left,不如更改width(这样可以避免溢出问题)。
- 为什么要同时保留
menu_links 和active?一个就够了