抱歉,如果我的问题确实是针对新手级别的......
我有一个 3 级列表来构建菜单,但我不想使用 href。 我想改用特定的属性并用它的值调用 javascript 函数。
这是我的示例列表的标记:
<ul class="menu">
<li><a href="#" link_value="item 1">Firts level Menu item 1</a></li>
<ul>
<li><a href="#" link_value="item 2-1">Second level Menu item 1</a></li>
<ul>
<li><a href="#" link_value="item 3-2-1">Third level Menu item 1</a></li>
<li><a href="#" link_value="item 3-2-2">Third level Menu item 2</a></li>
<li><a href="#" link_value="item 3-2-3">Third level Menu item 3</a></li>
</ul>
<li><a href="#" link_value="item 2-2">Second level Menu item 2</a></li>
<li><a href="#" link_value="item 2-3">Second level Menu item 3</a></li>
</ul>
<li><a href="#" link_value="item 2">Firts level Menu item 2</a></li>
<li><a href="#" link_value="item 3">Firts level Menu item 3</a></li>
我怎样才能运行一个javascript函数来为所有项目设置onclick事件以具有类似的内容
<a onclick="my_fynction()">
function my_fonction() {do_something(link_value)}
并且还向活动元素及其父级添加一个“活动”类,并从其他元素中删除活动类?
希望我已经说得足够清楚了? 非常感谢!!!
您可以监听
ul.menu
上的点击,并将事件逻辑仅放在该元素上。
document.querySelector('ul.menu').addEventListener('click', event => {
// event.target is clicked element
if(event.target.tagName!=="A") return;
// prevent default behaviour; redirecting
event.preventDefault();
// your code...
})
但是,如果您将
<span>
放在 <a>
内,则需要小心。您需要将 CSS pointer-events: none;
放在这些元素上。
关于我的上述两条评论...
@jeromebg ...
是无效的属性名称。请考虑使用link_value
全局属性 和 DOM 元素的相关data-*
属性 ... 例如 ...dataset
,其中每个值都可以这样读取 ...<a href="#" data-value="item 3"/>
。linkElement.dataset.value
@jeromebg ...嵌套的
标记也已损坏/无效...请修复它。<ul/>
...修复标记后,应该使用(如已建议但未明确命名的)event-delegation。
后者不仅意味着在公共(外部)根节点处监听,还意味着针对感兴趣的元素,这些元素(如根节点)也可能具有子元素节点。
closest
的 event
元素的 target
方法来实现结果。
关于OP的另一个要求......
...还向活动元素及其父级添加一个“活动”类,并从其他元素中删除活动类?
...处理程序函数会将当前标识的链接元素传递给自定义实现的函数,从而转发这样的特殊任务,而不是自行处理此类内容。
标记当前菜单项的函数必须执行以下操作...
识别菜单项节点...由...完成
const menuItem = elmLink.closest('li');
识别菜单根节点...由...完成
const menuRoot = menuItem.closest('ul.menu');
选择正确的选择器来查询具有链接元素(例如
'li:has(a[href])'
)的任何列表项节点,并从每个查询的元素中删除预期的类名称(和/或例如aria属性)。
将预期的类名(和/或例如 aria 属性)添加到已标识为 current 的列表项。
无需将另一个列表项的 current 状态涉及的任何列表项也标记为 current。通过利用像
:has()
这样的函数式 CSS 伪类,可以轻松实现这种状态的视觉表示
function markCurrentMenuItem(elmLink) {
const menuItem = elmLink.closest('li');
const menuRoot = menuItem.closest('ul.menu');
menuRoot
.querySelectorAll('li:has(a[href])')
.forEach(elm => {
// elm.classList.remove('active');
elm.removeAttribute('aria-current');
});
// menuItem.classList.add('active');
menuItem.setAttribute('aria-current', 'true');
}
document
.querySelector('ul.menu')
.addEventListener('click', evt => {
const elmLink = evt.target.closest('a[href][data-value]')
if (elmLink) {
evt.preventDefault();
markCurrentMenuItem(elmLink);
console.log({ value: elmLink.dataset.value });
}
})
body { margin: 0; }
ul { list-style: none; margin: 0; padding: 0 0 0 20px; }
li { padding: 2px 0 2px 0; }
a span { display: inline-block; padding: 0 20px; background-color: #f2ffa7; }
/* li.active, */li[aria-current="true"] a > span {
background-color: #b1d000;
}
/* ul:has(> li.active), */ul:has(> li[aria-current="true"]) {
background-color: #bee8ff;
}
.as-console-wrapper { left: auto!important; width: 50%; min-height: 100%; }
<ul class="menu" role="menu" aria-label="Main Menu">
<li>
<a href="#" data-value="item 1">
<span>First level Menu item 1</span>
</a>
</li>
<li>
<ul role="menu" aria-label="Second Level Menu">
<li>
<a href="#" data-value="item 2-1">
<span>Second level Menu item 1</span>
</a>
</li>
<li>
<ul role="menu" aria-label="Third Level Menu">
<li>
<a href="#" data-value="item 3-2-1">
<span>Third level Menu item 1</span>
</a>
</li>
<li>
<a href="#" data-value="item 3-2-2">
<span>Third level Menu item 2</span>
</a>
</li>
<li>
<a href="#" data-value="item 3-2-3">
<span>Third level Menu item 3</span>
</a>
</li>
</ul>
</li>
<li>
<a href="#" data-value="item 2-2">
<span>Second level Menu item 2</span>
</a>
</li>
<li>
<a href="#" data-value="item 2-3">
<span>Second level Menu item 3</span>
</a>
</li>
</ul>
</li>
<li>
<a href="#" data-value="item 2">
<span>First level Menu item 2</span>
</a>
</li>
<li>
<a href="#" data-value="item 3">
<span>First level Menu item 3</span>
</a>
</li>
</ul>