如何在 JS 中存储点击事件的一些数据?

How to store some data on a click event in JS?

我正在用 js 制作一个 Analytics 应用程序。我需要从被点击的元素中获取文本。 我目前正在使用这个函数来获取数据

clickfunc = function(link) {
var t = link.innerText || link.textContent;
console.log(t);
}

我在 link 上调用此函数为-

<a href="#work" onclick='clickfunc(this)'>

问题是,我需要从元素中获取数据而不调用代码中的函数,就像在 GTM 中一样。

感谢任何帮助。

Here as I have called the function in <a href="#work" onclick='clickfunc(this)'>, I need to make a function that does not have to be called like this.

听起来你在问如何使用现代事件处理,这是个好主意。

您通过以下方式完成:

  1. 从该标签中删除 onclick,并且:
    1. 添加在该元素创建后运行的脚本并为其挂接处理程序;或
    2. 添加挂钩 click 祖先元素的脚本,然后在点击冒泡到该祖先元素时检查它是否通过了该元素。 (这称为 事件委托。)

这是#1 的示例:

<a href="#work">this is the #work element</a>
<a href="#life">this is something else</a>
<script>
document.querySelector("a[href='#work']").addEventListener("click", function() {
    console.log(this.textContent || this.innerText);
});
</script>

请注意,必须在 元素存在后 评估该代码。在现代浏览器上有几种方法可以做到这一点:

  1. 将其放在文档末尾的 script 标记中,就在结束 </body> 标记之前。这适用于现代、旧版和过时的浏览器。
  2. 或者将 defer 属性放在 script 标签上(假设您使用的是带有 src 的外部脚本;它不适用于内联脚本)。适用于现代浏览器。
  3. 或者将代码包装在 DOMContentLoaded 事件的处理程序中。适用于现代和旧版浏览器。

这是#2(事件委托)的示例:

<script>
document.addEventListener("click", function(e) {
    var a = e.target.closest("a[href='#work']");
    if (a) {
        // The event passed through the element on its way to the document
        console.log(a.textContent || a.innerText);
    }
});
</script>
<a href="#work">this is the #work element</a>
<a href="#life">this is something else</a>

closest 方法存在于现代和稍旧的浏览器中,但不存在于 IE11 中。如果需要使用兼容IE11的代码:

document.addEventListener("click", function(e) {
    var a = e.target;
    while (a && a.nodeType === 1) {
        if (a.tagName === "A" && a.getAttribute("href") === "#work") {
            // The event passed through the element on its way to the document
            console.log(a.textContent || a.innerText);
            break;
        }
        a = a.parentNode;
    }
});

在您提出的评论中:

Can I do it like var a = e.target.closest("a[href]") to reference all the tags having href?

是的,就是这样。 e.target.closest("a[href]") 将匹配第一个具有 href 属性的 a 元素,从 e.target 开始并向上移动到其祖先。 e.target.closest("a[href^='#']") 只会对 ahref# 开头的元素执行此操作。例如,上面的示例中有两个 href="#xyz" 元素记录了它们的文本,第三个 href="http://example.com" 没有记录它们的文本,因为它不匹配:

<script>
document.addEventListener("click", function(e) {
    var a = e.target.closest("a[href^='#']");
    if (a) {
        // The event passed through the element on its way to the document
        console.log(a.textContent || a.innerText);
    }
});
</script>
<div><a href="#work">this is the #work element</a></div>
<div><a href="#life">this is the #life element</a></div>
<div><a href="http://example.com">this is the http://example.com element</a></div>

我已经把代码加到script标签里,放到head标签里了。因此,一旦 dom 被加载,它将为所有具有 href 的标签附加一个点击监听器。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.addEventListener('DOMContentLoaded', (event) => {
            document.querySelectorAll('a[href]').forEach(function (elms) {
                elms.addEventListener('click', function (link) {
                    var t = link.innerText || link.textContent;
                    console.log(t);
                });
            });
        });
    </script>
</head>

<body>
  <a href="#work">
  <a href="#abc">
</body>

</html>

我可以建议你需要像 global watcher 这样的东西吗?

document.addEventListener('click', watchAnchorClicks);

function watchAnchorClicks(event){
  if (event.target.tagName === 'A'){
    var anchor = event.target;
    console.log('Click on anchor with text ' + anchor.innerText + ' and href ' + anchor.href);
  }
}
<p>Paragraph with <a href="#anchor">anchor</a> in.</p>
<p>Yet another paragraph with other <a href="#another">other anchor</a> in.</p>