【问题标题】:Vanilla JavaScript getAttribute("href") from link with image insideVanilla JavaScript getAttribute("href") 来自与内部图像的链接
【发布时间】:2022-02-13 08:21:04
【问题描述】:

我正在尝试使用原生 JavaScript 创建选项卡,每个选项卡在链接内都有一个图标和一个标题

<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">

问题是当我在链接中有&lt;img&gt;&lt;h3&gt; 元素时,.getAttribute("href"); 返回 null。 如果我将标签更改为

,一切正常
<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 的任意位置时打开选项卡内容。如何在 vanilla 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;
}

【问题讨论】:

  • 如果您使用#fragment URLs 进行标签导航,您可以在纯CSS 中使用:target 伪类执行此操作。但仅供参考,您的代码不起作用,因为tabClickEvent.currentTarget 可能是链接的后代,而不是链接本身。
  • @Touffy 我相信你的意思是.target 而不是.currentTarget.target 将始终是实际点击的元素 - 可能是 img 或 h3 这里。 .currentTarget,根据定义,将是处理程序实际附加到的元素,这里是链接周围的 div。 (当然没有 href,但公平地说,这不是 OP 试图获得的 href。)
  • 我猜你的目标元素在这里是错误的。您可以使用debugger 调试它或尝试使用console.log(anchorReference); 来找出问题。
  • 好的,谢谢罗宾。

标签: javascript html image href getattribute


【解决方案1】:

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>  

【讨论】:

  • 谢谢! let anchorReference = tabClickEvent.target.closest('a'); 解决了问题
  • 在 click 事件上调用 preventDefault() 会破坏预期的浏览器行为,例如在新选项卡中打开或在按下修饰键时下载链接。您可以通过检查单击是否按下了其中一个键来解决此问题。
【解决方案2】:

首先:您可以使用 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为当前打开的标签页设置标签页链接的样式。

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

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

【讨论】:

  • 感谢您的提示。但是我注意到:target 被记录在Selectors Level 4 draft 版本中,而没有提及动态使用,_is 显示在this example on MDN 中。不幸的是,这个例子没有提到一个内在的缺点:如果目标显示是由 :target 在 CSS 中使用的,并且目标在内部链接中,使用内部链接会杀死目标的显示。不好:)
  • 是的,它有它的局限性。几十年来,它一直(ab)用于制作交互式纯 CSS 页面,比选项卡复杂得多,所以我不会担心规范没有明确说明它会动态地对导航状态做出反应。它不像 :hover 那样你可以有一个反馈循环,因为反应性。 URL 不能被 CSS 改变,只能反过来。
  • @traktor 还与 :local-link 一起,在不久的将来会以 developer.mozilla.org/en-US/docs/Web/CSS/:target-within 的形式回答您的限制;)
猜你喜欢
  • 2011-12-27
  • 2020-05-16
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 2021-06-30
  • 2016-05-17
相关资源
最近更新 更多