【问题标题】:How to convert this jQuery code to plain JavaScript?如何将此 jQuery 代码转换为纯 JavaScript?
【发布时间】:2020-05-07 15:24:50
【问题描述】:

我正在尝试在设置data-attribute 的链接上获取焦点方法(触摸、鼠标或键盘)。

$(function() {
    var i,
        r = document.getElementsByTagName("a")[0];

    if ("ontouchstart" in window) {
        document.addEventListener("touchstart", function(event) {
            i = "touch";
        }, true);
    }
    else {
        document.addEventListener("mousedown", function(event) {
            i = "mouse";
        }, true);
    }
    document.addEventListener("keydown", function(event) {
        i = "keyboard";
    }, true);
})

问题是我只得到了用 jQuery 编写最后一部分的结果:

    $("a").focus(function() {
        $(this).attr("data-focus-method", i)
    })
    $("a").blur(function() {
        $(this).removeAttr("data-focus-method")
    })

我想用纯 JavaScript 编写整个代码。我试过下面的方法:

    r.addEventListener("focus", function() {
        r.setAttribute("data-focus-method", i);
    });
    r.addEventListener("blur", function() {
        r.removeAttribute("data-focus-method");
    });

但它不起作用。 有人可以帮帮我吗?

【问题讨论】:

  • 这里的代码和你的实际代码一样吗?当您提到“on links”时,此行似乎很可疑r = document.getElementsByTagName("a")[0] - 即您的文本暗示多个/所有链接,但您的代码指示 first 链接(这在本身)。如果您实际上有类似for (var idx in document.getElementsByTagName("a")) { var r = document.getElementsByTagName("a")[idx] 的东西,那么这就是您的问题 - r 在它到达事件侦听器时会发生变化,因此使用this
  • @freedomn-m 问题是,当我删除 [0] 时,我收到“r.addEventListener 不是函数”错误消息。
  • 你的代码works just fine
  • @ArthurOtaviano 那是因为getElementsByTagName() 返回一个你需要遍历的nodeList 并在每个单独的元素上调用addEventListener
  • 这不是关于 删除 [0] - 更多的是你的真实代码使用[i](或类似的)?

标签: javascript jquery frontend web-frontend code-conversion


【解决方案1】:

我建议使用 querySelectorAll 方法并使用 forEach 来迭代节点列表

document.querySelectorAll("a").forEach((link) => {
  link.addEventListener("focus", function() {
    this.setAttribute("data-focus-method", i);
  });
  link.addEventListener("blur", function() {
    this.removeAttribute("data-focus-method");
  });
});

【讨论】:

  • 使用setAttribute 可以设置数据属性吗?我一直使用el.dataset 来做到这一点。
  • @YaakovAinspan 是的,确实如此
【解决方案2】:

我不确定您为什么要在键盘上按下某个键时尝试覆盖i on 方法。但是,我假设这是您想要的效果,因为您没有在问题中提及它。

也就是说,这里有一些东西可以让您更接近您的目标,即代码的 vanilla JS 版本。

答案使用spread operator 将您从getElementsByTagName 获得的nodeList 转换为数组,然后forEach() 循环遍历数组项。对于每个项目,我们添加两个event listeners.,一个用于focus,一个用于blur

当聚焦时,我们添加属性。当模糊时,我们删除该属性。我选择了set attributeremove attribute,但如果你愿意,也可以使用dataset

为了确定i(方法)是什么,我使用了letternary operator

我仍然不确定为什么要在键盘上按下一个键时覆盖该方法,所以我离开了。如果你让我知道想要的效果是什么,我可以改进它。

let i = ("ontouchstart" in window) ? "touch" : "mouse";

document.addEventListener("keydown", () => {
  i = "keyboard"
})

const links = [...document.getElementsByTagName("a")];

links.forEach(link => {
  link.addEventListener("focus", () => {
    link.setAttribute('data-focus-method', i);
  });
  link.addEventListener("blur", () => {
    link.removeAttribute('data-focus-method');
  })
})
<a href="#">My link 1</a>
<a href="#">My link 2</a>
<a href="#">My link 3</a>

【讨论】:

    【解决方案3】:

    我得到了解决方案:

        var w;
        for (w = 0; w < r.length; w++) {
            r[w].addEventListener("focus", function() {
                this.setAttribute("data-focus-method", i);
            });
    
            r[w].addEventListener("blur", function() {
                this.removeAttribute("data-focus-method");
            });
        }
    

    顺便感谢所有帮助过我的人!

    【讨论】:

      猜你喜欢
      • 2020-09-29
      • 2020-07-24
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      相关资源
      最近更新 更多