I am making an Analytics app in js. I need to get the text from an element that is clicked. I am using this function to get the data at present.
clickfunc = function(link) {
var t = link.innerText || link.textContent;
console.log(t);
}
I call this function on a link as-
<a href="#work" onclick='clickfunc(this)'>
The problem is that, I need to get the data from the element without calling the function in the code, just like in GTM.
Any help is appreciated.
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.
It sounds like you're asking how to use modern event handling, which is a good idea.
You do it by:
onclick
from that tag, and either:
click
on an ancestor element and then checks, when the click bubbles to that ancestor, whether it passed through that element. (This is called event delegation.)Here's an example of #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>
Note that that code must be evaluated after the element exists. There are several ways to do that on modern browsers:
script
tag at the end of the document, just before the closing </body>
tag. This works on modern and older and obsolete browsers.defer
attribute on the script
tag (this assumes you're using an external script with a src
; it doesn't work on inline script). Works on modern browsers.DOMContentLoaded
event. Works on modern and older browsers.Here's an example of #2 (event delegation):
<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>
That closest
method exists on modern and slightly older browsers but not IE11. If you need to use IE11-compatible code:
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;
}
});
In a comment you asked:
Can I do it like
var a = e.target.closest("a[href]")
to reference all the tags having href?
Yes, that's it exactly. e.target.closest("a[href]")
will match the first a
element that has an href
attribute starting from e.target
and moving up through its ancestors. e.target.closest("a[href^='#']")
will do that only for a
elements whose href
starts with #
. For instance, here's the example above with two href="#xyz"
elements that log their text and a the third href="http://example.com"
that doesn't because it doesn't match:
<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>