sans-serif   serif

«

MooTools for Beginners Part 4 – Selecting and Manipulating DOM Elements

January 12, 2010

Most of the time the whole point of using mootools is to manipulate an element or collection of elements. (But not always, as you’ll see in Part 5.) Now that you know some basics we’re going to get more in depth by learning the various ways to select dom elements to manipulate them–traversing the dom, as it were.

Selecting DOM Elements

The most common ways to select an element or elements are to use the dollar function and pass in the string for the id of an element or to use the dollars function and pass in a CSS 3 selector:

var el = $('someElementId'); // single element
var someElements = $$('ul#fancy > li.css3'); // element collection

Once you’ve got an element you can do some other cool stuff to find other elements.

$('someElement').getElement('form'); // returns the first match
el.getElements('li.css3 > b.selector'); // returns all matches
el.getParent(); // very helpful
el.getPrevious(); // gets the previous element
el.getNext(); // duh
el.getAllNext(); // every sibling after
el.getChildren(); // but not grandchildren

It’s pretty obvious how to go down and select children elements, but note getParent, that’s how you go back up. Chain that with getNext or getPrevious and you can get yourself pretty much anywhere.

$('element').getParent().getNext();

In all of these you can pass in a CSS selector to match exactly what you want:

el.getChildren('input[name=importantStuff]');

And speaking of operators (that’s the = in the selector), we can do all of this:

el.getElements('div[title*=row]'); // contains `row`: ie `row-5`, `row-345`, `84row30`
el.getElements('div[class^=row]); // starts with `row`: ie `row-5` but not `joe-row-50`

Here they all are:

  • ‘=’ : is equal to
  • ‘*=’: contains
  • ‘^=’ : starts-with
  • ‘$=’ : ends-with
  • ‘!=’ : is not equal to
  • ‘~=’ : contained in a space separated list
  • ‘|=’ : contained in a ‘-’ separated list

Crazy selector demo

Something a little unexpected — a list filter using selectors

That’s pretty sweet for using hardly anything other than a selector. Now, I have to come clean here, this isn’t really the best way to do something like this–but it’s a great demonstration of how to select elements with mootools.

Notice inside of the filterList function we’ve got this code:

$$('li').setStyle('display','none');

$$ returns an array of elements. When you call a method on an array it will automatically enumerate over every element in the array. Pretty nice, I think. However, it can cause a bad habit:

// bad habit
$$('li').setStyle('display','none').fade('hide').set('title', title).fade('in');

That is going to do four loops over every element in the array. That’s dumb. Instead you should use each if you need to do more than one thing to the elements.

$$('li').each(function(element, index){
  element.setStyle('display','none').fade('hide').set('title', title).fade('in');
});

Now we just do one loop. Much easier on the browser.

Speed up your selectors

Sometimes you see code out in the wild that is selector happy:

// Bad
$('someDiv').setStyle('color','red');
$('someDiv').fade('hide');

$('otherDiv').set('tween',{duration: 1000})
$('otherdiv').fade('hide');

// elsewhere on the page
$('otherDiv').fade('in');

It’s better to cache your elements and then call methods on the reference, or if you’re only messing with it once, chain the methods together.

// Good
$('someDiv').setStyle('color','red').fade('hide');

var otherDiv = $('otherDiv').set('tween',{duration: 1000}).fade('hide');
// elsewhere on the page
otherDiv.fade('in');

Notice that var = otherDiv still gets the element even though we chained a couple methods on it. Each of those methods returns the element so the reference is correct. In fact, that’s the very reason chaining works at all.

Chistoph Pojer has even more tips here to speed up your site. General rule of thumb is to select things just once, and start close by including more information rather than less in your selector.

$$(‘input[name=password]‘).getParent().getParent()

MooTools in this article

Related Posts:

Comments

  • http://www.cbolson.com Chris Bolson

    Some good clear explanations here Ryan as always.

    I’m particulary interested in your filter demo as you may remember I was working on some code recently that included a filter. I actually did it slightly differently than your example by testing the actual li values but I must admit to like the way that you have done it, ie by inserting the text value to the title and then using the selector. However you say that “it isn’t really the best way to do something like this…” Why do you say that? I would be interested in seeing how you would use an alternative method for achieving the same results :)

    Thanks

    Chris

  • Ryan Florence

    @Chris: When using $$ if I’ve got a list that’s very large (thousands?) with fairly long text in each li I’d be concerned about performance for some users–but it may very well be viable, it would just require some testing. I’d probably want to cache the elements and filter them some other way rather than select them on every keyup, it just feels excessive.

    Also, aside from being caps insensitive, the filter isn’t very intelligent, it’s pretty easy to get strange results (type “the Hedgehog” and you see nothing when you should see two items.)

    So, I’d do some sort of caching of the elements and their contents in an object maybe and then build a more intelligent filtering function that checks the object, instead of selecting the elements directly, and then hides or displays the items based on matches.

  • http://www.cbolson.com Chris Bolson

    @Ryan Hmm, true about the Hedgehog :(

    Whilst I realise that you did the demo to demonstrate the use of selectors, I have knocked up a quick demo using the method that I have been using which, by the way, resolves the missing Hedhehog issue: http://jsfiddle.net/Y5yJm/ This one directly compares the li text value (html) with the typed value.

    Clearly this demo doesn’t address the caching issue that you mention but I would be interested to know if you think that this method is worse, same or better than your example as regards performance.

    Chris

  • Ryan Florence

    Yours is 3x faster :) , I also included a cached version. Your browser will hang up for a sec while it’s figuring things out then open the console to see the results. http://jsfiddle.net/rpflorence/Y5yJm/2/

  • http://www.cbolson.com Chris Bolson

    Thanks for that confirmation. I suppose your version is that much slower as it first has to modify the elements to add the title.

    I need to look closer at how you have cached the items as that could possibly shave a few milliseconds off the script that I have done ;)

  • http://blog.computer-service-mallorca.com Michael Pehl

    Very nice and clear explanations. Thank you for providing this tutorials :)

  • http://blog.computer-service-mallorca.com/2010/01/17/mootools-for-beginners-part-4-and-5/ MooTools for Beginners Part 4 and 5 | MooTools and CSS Resources

    [...] 4 of his great tutorial series is here and Part 5 is here. Enjoy. [...]

blog comments powered by Disqus

Comments RSS