I wrote the following code for a project that I'm working on:
var clicky_tracking = [
['related-searches', 'Related Searches'],
['related-stories', 'Related Stories'],
['more-videos', 'More Videos'],
['web-headlines', 'Publication']
];
for (var x = 0, length_x = clicky_tracking.length; x < length_x; x++) {
links = document.getElementById(clicky_tracking[x][0])
.getElementsByTagName('a');
for (var y = 0, length_y = links.length; y < length_y; y++) {
links[y].onclick = (function(name, url) {
return function() {
clicky.log(url, name, 'outbound');
};
}(clicky_tracking[x][1], links[y].href));
}
}
What I'm trying to do is:
id
attribute value (e.g., "related-searches") and a corresponding description (e.g., "Related Searches");document
with the corresponding id
attribute, and then gather a collection of all <a>
elements (hyperlinks) within it;onclick
handler to each hyperlink, which should call clicky.log
, passing in as parameters the description that corresponds to the id
(e.g., "Related Searches" for the id
"related-searches") and the value of the href
attribute for the <a>
element that was clicked.Hopefully that wasn't thoroughly confusing! The code may be more self-explanatory than that.
I believe that what I've implemented here is a closure, but JSLint complains:
http://img.skitch.com/20100526-k1trfr6tpj64iamm8r4jf5rbru.png
So, my questions are:
onclick
event handlers to the document
elements with the id
attributes in my arrays, and then looking at event.target
? I've done that once before and understand the theory, but I'm very hazy on the details, and would appreciate some guidance on what that would look like - assuming this is a viable approach.Thanks very much for any help!
Delegation is a better approach. JSLint complains because you are creating a new function each time within the loop. However, instead of setting up a single event on the document to listen for all click events, I would rather setup a handler on all individual root elements that have id's assigned to them. A single handler can be reused for all these elements.
function logClick(event) {
event = event || window.event;
var link = event.target || event.srcElement;
if(link.nodeName.toLowerCase() !== "a") {
return;
}
var name = clicky_tracking[this.id];
clicky.log(link.href, name, 'outbound');
}
Register the above handler with each root element.
for(var id in clicky_tracking) {
var root = document.getElementById(id);
root.onclick = logClick;
}
Also to avoid searching through the array, I've changed clicky_tracking
from array to an object for easier keyed access.
var clicky_tracking = {
'related-searches': 'Related Searches',
'related-stories': 'Related Stories',
'more-videos': 'More Videos',
'web-headlines': 'Publication'
};