簡體   English   中英

如何僅使用 Vanilla Javascript 在不知道其位置的情況下定位子節點

[英]How to Target a Child Node Without Knowing Its Position Using Only Vanilla Javascript

我創建了一個模型導航欄,並使用mouseenter事件,已​​經能夠在其父li元素內顯示子菜單。

這是通過使用children屬性和定位子菜單的位置來實現的,但是想知道如何在不知道的情況下實現這一點,或者是否有更好的慣用方法。

子菜單和列表項具有相同的類名。

在下面,您將找到我的代碼:

 'use strict'; var dropdown = document.getElementsByClassName('dropdown'); document.addEventListener('DOMContentLoaded', function(e) { e.preventDefault(); Array.from(dropdown).forEach(function(node) { node.addEventListener('mouseenter', function(event) { event.target.children[1].style.display = 'block'; }); }); Array.from(dropdown).forEach(function(node) { node.addEventListener('mouseleave', function(event) { event.target.children[1].style.display = 'none'; }); }); });
 *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } header { height: 20vh; width: 100vw; background-color: #000; } .navbar { position: relative; width: 100%; margin: 0; padding: 0; float: left; } .navbar > li { display: inline-block; list-style-type: none; position: relative; float: left; margin: 0; padding: 0; } .navbar li a { text-align: center; padding-left: 30px; white-space: nowrap; } .menu { display: none; position: absolute; top: 100%; left: 0; padding: 0; } .menu > li { list-style-type: none; padding: 10px 0; float: none; } li { width: 100px; } a { font-family: Helvetica Neue; text-decoration: none; color: #fff; display: block; }
 <header> <nav> <ul class="navbar"> <li class="dropdown"><a href="#">I drop down</a> <ul class="menu"> <li><a href="#">1</a></li> <li><a href="https://google.co.uk">2</a></li> </ul> </li> <li class="dropdown"><a href="#">So do I</a> <ul class="menu"> <li><a href="#">3</a></li> <li><a href="https://stackoverflow.com">4</a></li> </ul> </li> <li><a href="#">No effect</a></li> <li><a href="#">Same here</a></li> </ul> </nav> </header>

一種選擇是向目標元素添加id s(或class es),然后向控制元素添加一些屬性以表示它控制的目標元素。 在不了解兩個節點之間的 DOM 關系的情況下,您將不得不添加一些信息來連接它們。

我打算使用data-屬性,但后來我想起通過使用aria-controls你也可以添加一些 a11y。

 'use strict'; var dropdown = document.getElementsByClassName('dropdown'); document.addEventListener('DOMContentLoaded', function(e) { e.preventDefault(); Array.from(dropdown).forEach(function(node) { node.addEventListener('mouseenter', function(event) { var menuId = event.srcElement.getAttribute('aria-controls'); document.getElementById(menuId).style.display = 'block'; }); node.addEventListener('mouseleave', function(event) { var menuId = event.srcElement.getAttribute('aria-controls'); document.getElementById(menuId).style.display = 'none'; }); }); });
 *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } header { height: 20vh; width: 100vw; background-color: #000; } .navbar { position: relative; width: 100%; margin: 0; padding: 0; float: left; } .navbar > li { display: inline-block; list-style-type: none; position: relative; float: left; margin: 0; padding: 0; } .navbar li a { text-align: center; padding-left: 30px; white-space: nowrap; } .menu { display: none; position: absolute; top: 100%; left: 0; padding: 0; } .menu > li { list-style-type: none; padding: 10px 0; float: none; } li { width: 100px; } a { font-family: Helvetica Neue; text-decoration: none; color: #fff; display: block; }
 <header> <nav> <ul class="navbar"> <li class="dropdown" aria-controls="menu1"><a href="#">I drop down</a> <ul class="menu" id="menu1"> <li><a href="#">1</a></li> <li><a href="https://google.co.uk">2</a></li> </ul> </li> <li class="dropdown" aria-controls="menu2"><a href="#">So do I</a> <ul class="menu" id="menu2"> <li><a href="#">3</a></li> <li><a href="https://stackoverflow.com">4</a></li> </ul> </li> <li><a href="#">No effect</a></li> <li><a href="#">Same here</a></li> </ul> </nav> </header>

另一種方法(我更喜歡)是使用 HTML 的結構來查找節點。 為此, ul.menu必須是currentTarget的后代。 然后你可以使用querySelector來定位它。

 'use strict'; var dropdown = document.getElementsByClassName('dropdown'); document.addEventListener('DOMContentLoaded', function(e) { e.preventDefault(); Array.from(dropdown).forEach(function(node) { node.addEventListener('mouseenter', function(event) { this.querySelector(':scope > ul.menu').style.display = 'block'; }); node.addEventListener('mouseleave', function(event) { this.querySelector(':scope > ul.menu').style.display = 'none'; }); }); });
 *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } header { height: 20vh; width: 100vw; background-color: #000; } .navbar { position: relative; width: 100%; margin: 0; padding: 0; float: left; } .navbar > li { display: inline-block; list-style-type: none; position: relative; float: left; margin: 0; padding: 0; } .navbar li a { text-align: center; padding-left: 30px; white-space: nowrap; } .menu { display: none; position: absolute; top: 100%; left: 0; padding: 0; } .menu > li { list-style-type: none; padding: 10px 0; float: none; } li { width: 100px; } a { font-family: Helvetica Neue; text-decoration: none; color: #fff; display: block; }
 <header> <nav> <ul class="navbar"> <li class="dropdown"><a href="#">I drop down</a> <ul class="menu"> <li><a href="#">1</a></li> <li><a href="https://google.co.uk">2</a></li> </ul> </li> <li class="dropdown"><a href="#">So do I</a> <ul class="menu"> <li><a href="#">3</a></li> <li><a href="https://stackoverflow.com">4</a></li> </ul> </li> <li><a href="#">No effect</a></li> <li><a href="#">Same here</a></li> </ul> </nav> </header>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM