Element Collection Manipulation Shortcut Using MooTools 1.2

By  on  

One mistake I've been making with MooTools is that I've been looping through element collections (retrieved by using $$ function) to add events and manipulate elements. When you've got an element collection, there's no need to loop through them. Why? Because you can simply add modification code to the element collection and MooTools does the looping internally. Let me illustrate my point below.

Let me use my mouseover accordion example code to illustrate my point.

MooTools Looping Example (Bad/Long)

$$('.toggler').each(function(el) {
	el.addEvent('mouseenter',function(e) {
		el.fireEvent('click');
	});
});

Above, we're looping through each item to add the event. This works fine but it's extra code.

MooTools Collection Example (Good/Short)

$$('.toggler').addEvent('mouseenter', function() { this.fireEvent('click'); });

In this snippet, we skip the looping process all together and simply apply the addEvent() code to the collection. We also use the this keyword as an element reference instead of the individual element object. Of course, MooTools loops through the element collection internally but the above example shows you how to achieve the same effect using much less code.

Recent Features

Incredible Demos

Discussion

  1. mmm, is this working with v1.11 too ?
    i think i tried, but did not managed to, but i think the “this” were the problem…

  2. @rborn: Not sure about Moo 1.11 … stop living in the past! :)

  3. yeah, would be nice…, only for now is not possible in some cases
    another question
    do u mind making a benchmark ? to compare this two methods.. :)

  4. Joao Resignado

    jQuery FTW :)

  5. I can’t believe I never knew you could do this! I will most definitely be using this method from now on. So much easier.

    As for 1.11 versus 1.2 – I’d much rather move on to 1.2 but there are still scripts that I depend on for sites that haven’t been moved over yet. I personally don’t know all of the difference in 1.2 so I can’t do it myself either.

    Until those scripts move ahead, there’s no reason for me to move my scripts ahead either so I’m stuck a bit.

  6. @Tim: Yeah, my 1.11 comment was in jest. I understand the relevance of 1.11.

  7. well, my main problem moving to v1.2 are clients… you cannot tell them that u gonna spend another X hours (paid hours :D ) to change their code, because a new version of moo is there…

  8. boiss

    MooTools seems just as cool as jQuery

    jQuery code to do this would be something like that :

    $('.toggler').mouseover(function() { $(this).click(); });
    

    Note: Untested…

  9. boiss: Thank you for posting the jQuery version!

  10. Wow, I never knew you could directly interact with a collection like that. Thanks, David!

  11. mxrtin

    afaik it works in mootools 1.11
    for example:

    $$("a").addEvent("focus",function(){ this.blur(); });
    

    to get rid of the fug dotted border on active links..

  12. Jaik

    @david: Nice post. It’s a great feature of element collections that surprisingly few people know about :)

    @mxrtin: That works but is a pretty nasty way of doing it! Try this in your CSS instead:

    a {outline:0;}
    

    Really you should define your own :focus styles if you’re doing this.

  13. mark

    The only problem that I have with doing it this way is binding;

    $$(collection).addEvent('click', function(e){
    //this is no longer the element and im not sure how to get to the element
    }.bind(this));
    

    the way around it would be to set var that = this; and not bind it

  14. @mark the easiest way I can think of to get to the element would be to use the click event.

    $$('#collection .selector').addEvent('click',function(e) {
        var evt = new Event(e);
        var element = evt.target;
        // do stuff
    }.bind(this));
    

    I haven’t done this recently but I’m 99% sure it works.

  15. Jaik

    @Bryan J Swift: You can take out one of those lines in 1.2…

    $$('#collection .selector').addEvent('click', function(e){
        var element = e.target;
        // do stuff
    }.bind(this));
    

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!