views:

4186

answers:

2

I am going to be starting a javascript reporting engine for my website, and have started some prototyping using MooTools. I really like being able to do things like this:

function showLeagues(leagues) {
    var leagueList = $("leagues");
    leagueList.empty();
    for(var i = 0; i<leagues.length; ++i) {
     var listItem = getLeagueListElement(leagues[i]);
     leagueList.adopt(listItem);
    }
}

function getLeagueListElement(league) {
    var listItem = new Element('li');
    var newElement = new Element('a', {
        'html': league.name,
        'href': '?league='+league.key,
        'events': {
             'click': function() { showLeague(league); return false; }
        }
    });
    listItem.adopt(newElement);
    return listItem;
}

From what I've seen, jQuery's "adopt" type methods only take html strings or DOM Elements. Is there any jQuery equivalent to MooTools' Element?


EDIT: The big thing I'm looking for here is the programmatic attachment of my click event to the link.

+4  A: 

Here's that same thing in jQuery. Basically to create a new element, you just put in the HTML you want.

function showLeagues(leagues) {
    var $leagueList = $("#leagues");
    $leagueList.empty();
    $.each(leagues, function (index, league) {
        $leagueList.append(getLeagueListElement(league));
    });
}

function getLeagueListElement(league) {
    return $('<li></li>')
        .append($('<a></a>')
            .html(league.name)
            .attr('href', '?league=' + league.key)
            .click(function() {
                showLeague(league);
                return false;
            })
        )
    ;
}
nickf
Instead of $('<li></li>') you can just use $('<li/>') btw
J-P
good catch Jimmy.
Chris Marasti-Georg
do note, the "<li/>" code is sub-optimal, and looking at the code shows that jquery does regexp to expand it back to "<li></li>" ;)
Kent Fredric
+3  A: 

syntactically, it may be nicer to use jQuery to do it, but its probably more efficient to use

  document.createElement('li')

And eliminate the need for at the bare minimum a string comparison test and a minor token parse.

flydom may also tickle your interest if you insist on generating a lot of dom nodes. ( It should be faster in theory, but have not tested it )


Note: Internally, jQuery("<html></html>") looks like it effectively does this(oversimplified):

jQuery(matcher) --> function(matcher)
{
   return jQuery.fn.init(matcher) --> function(matcher)
   {
      return  this.setArray(
        jQuery.makeArray(
           jQuery.clean(matcher) --> function(matcher)
           { 
               div = document.createElement('div');
               div.innerHTML = matcher;
               return div.childNodes;
           }
        )
      );
   }
}

So one would presume "document.createElement" is thus a "requirement", and if you know what you want out ( ie: not parising some 3rd party data with $( datahere ) ) then document.createElement would imho be just as logical and with a speed boost to avoid the numerous regexps and slow string manipulations.

By comparison: jQuery(document.createElement('div')) looks like it effectively does this(oversimplified):

jQuery(matcher) --> function(matcher)
{
   return jQuery.fn.init(matcher) --> function(matcher)
   {
       this[0] = matcher; 
       this.length = 1; 
       return this; 
   }
}
Kent Fredric
Is there any browser that is modern enough to be supported by the main js libraries that doesn't include those DOM methods? My desire to use framework-specific code was twofold - one, to keep syntax consistent in my code, and two, to make sure I didn't have to care about browser differences.
Chris Marasti-Georg
Answer extended. From what i can tell, if the browser doesn't support document.createElement, then not even jQuery will work on it.
Kent Fredric
To be sure of your intent, you are saying that instead of: $('<a></a>').attr('href', '?league=' + league.key)..., you would recommend: $(document.createElement("a")).attr('href', '?league=' + league.key)... ?
Chris Marasti-Georg
yes. that is what *I* would do :)
Kent Fredric