来自 link 的 Vanilla JavaScript getAttribute("href"),里面有图片

Vanilla JavaScript getAttribute("href") from link with image inside

我正在尝试使用 vanilla JavaScript 创建标签,每个标签在 link

中都有一个图标和一个标题
<div class="tabs-bar-item">
  <a href="#tab3">
    <img class="icon" src="img/school.png">
    <h3 class="title">Instruktāžas datu aizsardzībā</h3>
  </a>
</div>

它应该打开选项卡内容

<div id="tab3" class="tabs-content-item">

问题是当我在 link 中有 <img><h3> 元素时,.getAttribute("href"); returns 为空。 如果我将选项卡更改为

,一切正常
<div class="tabs-bar-item">
    <img class="icon" src="img/school.png">
    <a href="#tab3">Instruktāžas datu aizsardzībā</a>
</div>

但我希望在 .tabs-bar-item 上的任意位置单击时打开选项卡内容。如何在原版中完成 JavaScript?

完整的JS代码:

let tabs = document.querySelectorAll('.tabs-bar .tabs-bar-item');

    function tabClicks(tabClickEvent) {
        for (let i = 0; i < tabs.length; i++) {
            tabs[i].classList.remove("active");
        }

        let clickedTab = tabClickEvent.currentTarget; 

        clickedTab.classList.add("active");
        tabClickEvent.preventDefault();

        let contentPanes = document.querySelectorAll('.tabs-content-item');

        for (i = 0; i < contentPanes.length; i++) {
            contentPanes[i].classList.remove("active");
        }

        let anchorReference = tabClickEvent.target;
        let activePaneId = anchorReference.getAttribute("href");
        let activePane = document.querySelector(activePaneId);

        activePane.classList.add("active");
    }

    for (i = 0; i < tabs.length; i++) {
        tabs[i].addEventListener("click", tabClicks)
    }

Css 选项卡内容:

.tabs-content .tabs-content-item {
    display: none;
}
.tabs-content .tabs-content-item.active {
    display: block;
}

Element.closest 向上搜索 DOM 以查找与作为参数传递的选择器匹配的元素。如果 Element 已经匹配选择器,则返回 Element(调用 closest 的节点)。

因此尝试改变

 let anchorReference = tabClickEvent.target;

 let anchorReference = tabClickEvent.target.closest('a');

例如

let tabs = document.querySelectorAll('.tabs-bar .tabs-bar-item');

function tabClicks(tabClickEvent) {
    for (let i = 0; i < tabs.length; i++) {
        tabs[i].classList.remove("active");
    }

    let clickedTab = tabClickEvent.currentTarget;

    clickedTab.classList.add("active");
    tabClickEvent.preventDefault();

    let contentPanes = document.querySelectorAll('.tabs-content-item');

    for (i = 0; i < contentPanes.length; i++) {
        contentPanes[i].classList.remove("active");
    }

    let anchorReference = tabClickEvent.target.closest('a');
    console.log( anchorReference);
    let activePaneId = anchorReference.getAttribute("href");
    let activePane = document.querySelector(activePaneId);

    activePane.classList.add("active");
}


for (i = 0; i < tabs.length; i++) {
    tabs[i].addEventListener("click", tabClicks)
}
.tabs-content .tabs-content-item {
    display: none;
}
.tabs-content .tabs-content-item.active {
    display: block;
}
<div class="tabs-bar">
  <div class="tabs-bar-item">
    <a href="#tab3">
      <img class="icon" src="img/school.png">
      <h3 class="title">Instruktāžas datu aizsardzībā</h3>
    </a>
  </div>
</div>
<div class=tabs-content>
  <div id="tab3" class="tabs-content-item">
     content of tab3 with self contained link: <a id="here" href="#here">here</a>. Clicking "here" should not close the tab!
  </div>
</div>  

首先:您可以使用 the :target pseudo-class 在纯 CSS 中执行此操作,不需要 JS。

.tabs-content .tabs-content-item {
    display: none;
}
.tabs-content .tabs-content-item:target {
    display: block;
}

在不久的将来,您还可以使用 the :local-link pseudo-class 为当前打开的标签设置标签 link 的样式。

在您的代码中,tabClickEvent.currentTarget 始终引用您附加侦听器的 DIV 元素。该元素没有 href。有多种方法可以解决这个问题。完全删除 DIV 将是一个好的开始,然后您可以将侦听器附加到 links,或者创建一个全局侦听器来检查它是否被单击 link 或其后代(使用 element.closest('a'))。

无论如何,使用 JavaScript 正确实现导航并不像您想象的那么容易(这也是纯 CSS 解决方案很好的原因)。例如,如果用户想在新的(浏览器)选项卡中打开 link,您必须添加一些代码以在加载时读取页面片段并在没有用户交互的情况下打开正确的选项卡。