2

I was writing a "pluginable" function when I noticed the following behavior (tested in FF 3.5.9 with Firebug 1.5.3).

$.fn.computerMove = function () {
    var board = $(this);
    var emptySquares = board.find('div.clickable');
    var randPosition = Math.floor(Math.random() * emptySquares.length);


    emptySquares.each(function (index) {
        if (index === randPosition) {
            // logs a jQuery object
            console.log($(this));
        }
    });

    target = emptySquares[randPosition];
    // logs a non-jQuery object
    console.log(target);
    // throws error: attr() not a function for target
    board.placeMark({'position' : target.attr('id')});
}

I noticed the problem when the script threw an error at target.attr('id') (attr not a function). When I checked the log, I noticed that the output (in Firebug) for target was:

<div style="width: 97px; height: 97px;" class="square clickable" id="8"></div>

If I output $(target), or $(this) from the each() function, I get a nice jQuery object:

[ div#8.square ]

Now here comes my question: why does this happen, considering that find() seems to return an array of jQuery objects? Why do I have to do $() to target all over again?

[div#0.square, div#1.square, div#2.square, div#3.square, div#4.square, div#5.square, div#6.square, div#7.square, div#8.square]

Just a curiosity :).

3
  • 1
    Probably not related, but html id's are supposed to start with a-zA-Z. Commented Apr 8, 2010 at 22:33
  • 1
    Try target = emptySquares.find(':eq(' + randPosition + ')'); Commented Apr 8, 2010 at 22:44
  • 1
    In answering the question, I forgot the how to do it part: for this use emptySquares.eq(randPosition) to get a jQuery element at that position (0 based). Commented Apr 8, 2010 at 23:00

2 Answers 2

5

.find() returns not an array of jQuery objects, but one jQuery object containing an array of DOM elements (a jQuery object, at it's core, is a wrapper around a DOM element array).

When you're iterating through, each element you're on is a DOM element. So, it needs to be wrapped in $(this) to become jQuery object and have access to those methods.

Also as a side note: The id attribute can't begin with a number, since it's invalid HTML you may or may not experience strange behavior, especially cross-browser (this rule applies for any invalid HTML).

Sign up to request clarification or add additional context in comments.

1 Comment

+1. Therefore: document.getElementById("id"); is equivalent to $("#id")[0];
0

No, the find method doesn't return an array of jQuery objects. You are creating a jQuery object for each element here:

console.log($(this));

If you log the value without creating a jQuery object from it:

console.log(this);

you will see that it's an element, not a jQuery object.

When you access the jQuery object as an array, you get an element. If you want a jQuery object you have to create one from the element.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.