如何重构此 JavaScript 代码以避免使函数处于循环中?
我为我正在从事的项目编写了以下代码:
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));
}
}
我想做的是:
- 定义一个二维数组,每个实例的内部数组包含两个元素:一个
id
属性值(例如“相关搜索”)和相应的描述(例如“相关搜索”); - 对于每个内部数组,在
document
中查找具有相应id
属性的元素,然后收集所有的集合> 其中的元素(超链接);
- 循环遍历该集合,并将
onclick
处理程序附加到每个超链接,该处理程序应调用clicky.log
,并将与id
对应的描述作为参数传递code>(例如,id
“相关搜索”的“相关搜索”)以及href 属性的值code> 被单击的元素。
希望这没有完全令人困惑!该代码可能比这更不言自明。
我相信我在这里实现的是一个闭包,但 JSLint 抱怨:
http://img .skitch.com/20100526-k1trfr6tpj64iamm8r4jf5rbru.png
所以,我的问题是:
- 如何重构这段代码以使 JSLint 令人满意?或者,更好的是,无论 JSLint 有何想法,是否有一种我所缺少的最佳实践方法可以做到这一点?
- 我应该依赖事件委托吗?也就是说,将
onclick
事件处理程序附加到数组中具有id
属性的document
元素,然后查看event.target ?我以前做过一次并理解了理论,但我对细节非常模糊,并且希望获得一些关于它的外观的指导 - 假设这是一种可行的方法。
非常感谢您的帮助!
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:
- define a two-dimensional array, with each instance the inner arrays containing two elements: an
id
attribute value (e.g., "related-searches") and a corresponding description (e.g., "Related Searches"); - for each of the inner arrays, find the element in the
document
with the correspondingid
attribute, and then gather a collection of all<a>
elements (hyperlinks) within it; - loop through that collection and attach an
onclick
handler to each hyperlink, which should callclicky.log
, passing in as parameters the description that corresponds to theid
(e.g., "Related Searches" for theid
"related-searches") and the value of thehref
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:
- How can I refactor this code to make JSLint agreeable? Or, better yet, is there a best-practices way to do this that I'm missing, regardless of what JSLint thinks?
- Should I rely on event delegation instead? That is, attaching
onclick
event handlers to thedocument
elements with theid
attributes in my arrays, and then looking atevent.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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
授权是一种更好的方法。 JSLint 会抱怨,因为您每次都在循环内创建一个新函数。但是,我宁愿在分配了 id 的所有单个根元素上设置一个处理程序,而不是在文档上设置单个事件来侦听所有单击事件。单个处理程序可以重复用于所有这些元素。
向每个根元素注册上述处理程序。
另外,为了避免搜索数组,我将
clicky_tracking
从数组更改为对象,以便更轻松地进行键控访问。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.
Register the above handler with each root element.
Also to avoid searching through the array, I've changed
clicky_tracking
from array to an object for easier keyed access.这段代码不太可维护!我讨厌把 jQuery 强加给你,但这看起来对你来说非常有用,比如:
你可以通过向每个链接添加“trackable”类来启用跟踪,并使用例如 $ 将链接映射到查找表(this).attr('rel').
希望这是有道理的。
This code isnt very maintainable! I hate shoving jQuery down your throat but this looks like a situation where is would be very useful to you, something like:
You could enable tracking by adding class 'trackable' to each link, and map links to a lookup table by using eg $(this).attr('rel').
Hope that makes sense.
您可以创建一个函数来构建事件处理程序,例如:
我还认为 事件委托也是一个非常好的选择,你可以很容易地实现它:
You could create a function to build the event handlers, e.g.:
I also think that event delegation is also a really good option, you can implement it very easily: