【问题标题】:Vanilla JS target href on link with child elementsVanilla JS 目标 href 与子元素的链接
【发布时间】:2020-05-16 08:15:32
【问题描述】:

我正在尝试将链接的href 定位到某个类,但是当链接包含子元素时,e.srcElement 的结果似乎取决于您单击链接的位置。

无论我点击链接的哪个位置,如何定位父 <a-tag 的 href?点击圆圈给我链接的实际href值,但点击F给我“未定义”。

HTML 元素

<a href="https://www.facebook.com/sharer/sharer.php?u=myshorturl" class="social-share">
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" style="fill: #7f91a4;" class="at-icon at-icon-facebook"><g><path d="M22 5.16c-.406-.054-1.806-.16-3.43-.16-3.4 0-5.733 1.825-5.733 5.17v2.882H9v3.913h3.837V27h4.604V16.965h3.823l.587-3.913h-4.41v-2.5c0-1.123.347-1.903 2.198-1.903H22V5.16z" fill-rule="evenodd"></path></g></svg>
    <span class="sr-only">Share This</span>
</a>

原版 JS

var shareButtons = document.getElementsByClassName("social-share");

Array.prototype.forEach.call(shareButtons, function (lnk) {
    lnk.addEventListener("click", function (e) {
        e.preventDefault();

        e = (e ? e : window.event);
        var t = (e.target ? e.target : e.srcElement);

        console.log(t);
        console.log(t.href);
    });    
});

【问题讨论】:

  • 您可以访问回调中的lnk 变量...
  • Doh'...我现在觉得自己很蠢!
  • 每个人都会遇到这种情况,☺

标签: javascript html


【解决方案1】:
var shareButtons = document.getElementsByClassName("social-share");

Array.prototype.forEach.call(shareButtons, function (lnk) {
    lnk.addEventListener("click", function (e) {
        e.preventDefault();
        console.log(lnk.href);
    });    
});

在您的特定用例的上下文中,lnk 变量的作用域为 forEach 调用闭包,并且仍可在事件处理程序中访问。

【讨论】:

    【解决方案2】:

    使用event.currentTarget:

    const icons = document.querySelectorAll('.social-share');
    
    icons.forEach(function(icon){
      icon.addEventListener('click', function(e){
      
        // Prevent really going to Facebook
        e.preventDefault();
        
        // Check if currentTarget is the icon
        if (this !== e.currentTarget){
          return;
        }
    
        console.log(e.currentTarget.href);
      
      // bind icon here so that `this` in the function equals to icon
      }.bind(icon));
    });
    .social-share {
      width: 50px;
      height: 50px;
      display: block;
      border-radius: 50%;
      border: 1px solid black;
    }
    <a href="https://www.facebook.com/sharer/sharer.php?u=myshorturl" class="social-share">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" style="fill: #7f91a4;" class="at-icon at-icon-facebook"><g><path d="M22 5.16c-.406-.054-1.806-.16-3.43-.16-3.4 0-5.733 1.825-5.733 5.17v2.882H9v3.913h3.837V27h4.604V16.965h3.823l.587-3.913h-4.41v-2.5c0-1.123.347-1.903 2.198-1.903H22V5.16z" fill-rule="evenodd"></path></g></svg>
        <span class="sr-only">Share This</span>
    </a>

    【讨论】:

    • 为什么要绑定呢? icon 的作用域是您在其中创建事件绑定的闭包。它仍然可以在事件处理程序中访问。就像在 OP 中的 lnk 一样。
    【解决方案3】:

    可能有更好的方法来做到这一点,但您可以通过检查目标元素是否是您想要的元素来实现,如果不是,则开始冒泡直到找到它。
    比如:

    document.querySelectorAll(".social-share").forEach( (e) => {
      e.addEventListener( "click", (ev) => {
        ev.preventDefault();
        let aElement = ev.target;
        while(!aElement.classList.contains("social-share"))
          aElement = aElement.parentElement;
        console.log(aElement);
      } )
    });
    

    此方法有其危险,与while 循环相关的“危险”相同,但由于我们通过对类的查询选择来操纵点击事件,只要嵌套的子级没有相同的类名称,它将始终在侦听器设置它的第一个位置结束。

    您可以对您的代码执行相同的操作。我只是喜欢查询选择器,你可以很容易地推断出这个想法。

    【讨论】:

    • 如 cmets 中所述,它们仍然引用了 lnk。所有这些逻辑都是不必要的
    • 是的,确实。发帖后看到你的评论:-)
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2021-11-12
    • 2012-08-24
    • 2023-01-03
    • 2022-06-16
    相关资源
    最近更新 更多