Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add event listener for html class?

Tags:

javascript

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 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";
            });
        }
    }());
like image 588
bitokeev Avatar asked Jul 20 '11 13:07

bitokeev


People also ask

Can you add event listener to class?

To add an event listener to all elements with class: Use the document. querySelectorAll() method to select the elements by class. Use the forEach() method to iterate over the collection of elements.

How do you add a listener in HTML?

The addEventListener() method allows you to add event listeners on any HTML DOM object such as HTML elements, the HTML document, the window object, or other objects that support events, like the xmlHttpRequest object.


3 Answers

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/

like image 116
Orbiting Eden Avatar answered Oct 01 '22 11:10

Orbiting Eden


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

like image 37
Amir Ismail Avatar answered Oct 01 '22 11:10

Amir Ismail


// 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

like image 30
Raynos Avatar answered Oct 01 '22 13:10

Raynos