Javascript 如何为 html 类添加事件侦听器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6762557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add event listener for html class?
提问by bitokeev
If I have HTML like this:
如果我有这样的 HTML:
<a href="#" class="movieImg"><div class="previewBulk"></div></a>
<a href="#" class="movieImg"><div class="previewBulk"></div></a>
and Javascript like this:
和 Javascript 像这样:
var movie = document.getElementsByClassName("movieImg");
var preview = document.getElementsByClassName("preview");
Is there any way to addEventListener
to 2 movie a tag and preview div
tag?
I try for loop but when I do something like:
有什么办法可以addEventListener
给 2 电影一个标签和预览div
标签吗?我尝试 for 循环,但是当我执行以下操作时:
for(var i = 0, j=movie.length; i<j; i++){
movie[i].style.left = 100;
preview[i].style.left = 100;
}
I get Uncaught TypeError: Cannot read property 'style' of undefined
.
我明白了 Uncaught TypeError: Cannot read property 'style' of undefined
。
After change preview to previewBulk, i still get error, my code actually look like this
将预览更改为 previewBulk 后,我仍然收到错误消息,我的代码实际上是这样的
(function(){
var movie = document.getElementsByClassName("movieImg"),
preview = document.getElementsByClassName("previewBulk");
//result = [];
for(var i = 0, j=movie.length; i<j; i++){
movie[i].addEventListener("mouseover", function(){
preview[i].style.left = ((movie[i].offsetWidth-preview[i].offsetWidth)/2)+20;
preview[i].style.top = -(movie[i].offsetHeight+preview[i].offsetHeight);
preview[i].style.visibility = "visible";
});
movie[i].addEventListener("mouseout", function(){
preview[i].style.visibility = "hidden";
});
}
}());
回答by Orbiting Eden
document.getElementsByClassName
does not return an array. It returns a node list which is traversed like an XML file.
document.getElementsByClassName
不返回数组。它返回一个像 XML 文件一样遍历的节点列表。
<a href="#" class="movie"><div class="previewBulk"></div></a>
<a href="#" class="movie"><div class="previewBulk"></div></a>
<script>
var movie = document.getElementsByClassName("movie");
for(var i = 0; i<movie.length; i++){
movie.item(i).style.width = "100px";
}?
</script>
See jsfiddle: http://jsfiddle.net/Uy5fk/
见jsfiddle:http: //jsfiddle.net/Uy5fk/
回答by Raynos
// for each iterates over a list and runs a function for each element
var forEach = Array.prototype.forEach,
// query selector all runs a CSS selector and returns a list of elements
// matching the selector
$$ = document.querySelectorAll.bind(document);
// for each element in the list returned by the CSS selector
forEach.call($$('.movieImg, .preview'), function(v) {
// add an event listener to the click event
v.addEventListener('click', function(e) {
// and run some event handling code.
}, false);
});
Of course there's browser compliance issues. They need to support ES5 & DOM2 events. Use shims for browser compliance.
当然,还有浏览器合规性问题。他们需要支持 ES5 和 DOM2 事件。使用垫片以符合浏览器要求。
If you include
如果你包括
It should fix browser support. Of course FF4/ Chrome /safari5/ ie9 / Opera10+ already support these
它应该修复浏览器支持。当然FF4/ Chrome /safari5/ ie9 / Opera10+ 已经支持这些了
Edit:
编辑:
The problem is actually the "closures inside loops problem"as described in the javascript garden
问题实际上是javascript花园中描述的“循环内闭包问题”
回答by Amir Ismail
No tags with classname preview
so
没有带有类名的标签,preview
所以
var preview = document.getElementsByClassName("preview");
will cause that error
会导致那个错误
this line must be as follows
这一行必须如下
var preview = document.getElementsByClassName("previewBulk");
and as @raym0nd said the number of div
tags must be equal to the number of a
tags
正如@raym0nd 所说,div
标签的数量必须等于a
标签的数量
EDIT
编辑
the problem with your code is you used the index of for
loop inside the anonymous function but this function is called with mouseout
and mouseover
event and after finishing the for
loop try the following
你的代码的问题是你for
在匿名函数中使用了循环的索引,但是这个函数是用mouseout
和mouseover
事件调用的,在完成for
循环后尝试以下操作
var movie = document.getElementsByClassName("movieImg");
for(var i = 0, j=movie.length; i<j; i++){
movie[i].addEventListener("mouseover", function(){
var preview = this.getElementsByClassName("previewBulk")[0];
preview.style.left = ((this.offsetWidth-preview.offsetWidth)/2)+20;
preview.style.top = -(this.offsetHeight+preview.offsetHeight);
preview.style.visibility = "visible";
});
movie[i].addEventListener("mouseout", function(){
var preview = this.getElementsByClassName("previewBulk")[0];
preview.style.visibility = "hidden";
});
}
or test in jsFiddle
或在jsFiddle 中测试
回答by raym0nd
for(var i = 0, j=movie.length; i<j; i++){
movie[i].style.left = 100;
preview[i].style.left = 100;
}
does preview has the same length as movie? if not this gives you an error.
预览和电影的长度一样吗?如果不是,这会给你一个错误。
回答by Quentin
You have class="previewBulk"
and document.getElementsByClassName("preview");
你有class="previewBulk"
和document.getElementsByClassName("preview");
Your code assumes there will be as many elements of the class preview
as there are for movieImg
, but since you got the class name wrong, there are going to be zero such elements.
您的代码假定类的元素数量与preview
for 一样多movieImg
,但由于您弄错了类名,因此此类元素将为零。