If I have HTML like this:
<a href="#" class="movieImg"><div class="previewBulk"></div></a>
<a href="#" class="movieImg"><div class="previewBulk"></div></a>
and Javascript like this:
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:
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
.
After change preview to previewBulk, i still get error, my code actually look like 开发者_C百科this
(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";
});
}
}());
document.getElementsByClassName
does not return an array. It returns a node list which is traversed like an XML file.
<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/
// 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.
If you include
- ES5-Shim
- Flow.js
It should fix browser support. Of course FF4/ Chrome /safari5/ ie9 / Opera10+ already support these
Edit:
The problem is actually the "closures inside loops problem" as described in the javascript garden
No tags with classname preview
so
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
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
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
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.
You have class="previewBulk"
and 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.
精彩评论