user3129738
user3129738

Reputation: 1

Selecting an element with two selectors

I am trying to select elements on a class ,put them on an array. For each element in that class I want to select the "a" Tag and then I want to make a listener for each element, but this is a mess that seems impossible for me in JS. Heres the code I have so far.

var elemento = new Array();
var y=document.getElementsByClassName("thumbnails");

for (var i=0; i < y.length; i++) {
    elemento = ( y[i].getElementsByTagName("a"));
    elemento[0].addEventListener('click', function(){alert("jo")}, false);
}

This works for the first element but not for the rest, and yes, elemento is [0] because there's no more "a" tags inside each thumbnail.

Upvotes: 0

Views: 91

Answers (2)

cookie monster
cookie monster

Reputation: 10972

While .querySelectorAll is a good solution, it's important to understand how this would be handled without it.

What you simply need is an inner loop to loop over the current set of a elements held by the elemento variable.

var elemento;
var y = document.getElementsByClassName("thumbnails");
var handler = function(){alert("jo")};

for (var i=0; i < y.length; i++) {
    elemento = y[i].getElementsByTagName("a");
    for (var j = 0; j < elemento.length; j++) {
        elemento[j].addEventListener('click', handler, false);
    }
}

Notice that I use a different counter j for the inner loop since i is already in use.

Notice also that I moved the handler function to a variable outside the loop. This makes all the elements use the same function object, which is more efficient.


Side note:

You may also want to create some helper methods that will shorten the long method names, and convert them to Arrays. This allows you to use Array methods like .forEach().

var _slice = Function.call.bind([].slice);

function byClass(ctx, clss) {
    if (typeof ctx === "string") {
        clss = ctx;
        ctx = document;
    }
    return _slice(ctx.getElementsByClassName(clss));
}
function byTag(ctx, tag) {
    if (typeof ctx === "string") {
        tag = ctx;
        ctx = document;
    }
    return _slice(ctx.getElementsByTagName(tag));
}

That reduces your code to this:

var handler = function(){alert("jo")};

byClass("thumbnails").forEach(function(thumb) {
    byTag(thumb, "a").forEach(function(a) {
        a.addEventListener('click', handler, false);
    });
});

Upvotes: 1

VisioN
VisioN

Reputation: 145408

One short way for modern browsers is to use CSS selectors in querySelector:

var elements = document.querySelectorAll('.thumbnails a');
for (var i = 0, len = elements.length; i < len; i++) {
    elements[i].addEventListener('click', function() { ... }, false);
}

DEMO: http://jsfiddle.net/AApw2/

Upvotes: 3

Related Questions