1

Say I have a map on an array of elements. The callback function takes the index and the value at that position in the array.

If I wrap the array element that the callback receives in $(), it behaves as I expect. If I use it without wrapping it in $(), it gives an error.

var nonHiddenElements = $( "form :input" ).not(':hidden');

nonHiddenElements.map(function(index, element){

    input_id = $(element).attr('id');  // this works

    input_id = element.attr('id') ;    // this gives an error

})

Can someone explain how this works. Is this a jQuery quirk, or a JavScript thing?

What type of objects does my nonHiddenElements array contain exactly? What is element that gets passed to the callback? And mainly what is the $() doing?

13
  • presumably because it's the name or another kind of identifier of the element that is returned, and not the actual DOM object itself. Commented Nov 7, 2014 at 11:43
  • Ok, that makes sense. Where can I read up on this sort of thing. It seems implicit that I know these things in advance of every tutorial I read. Commented Nov 7, 2014 at 11:45
  • 2
    Have you tried element.id? .attr() is a jquery keyword. In order to use that you need to call jquery by using $(element). Commented Nov 7, 2014 at 11:45
  • @wobbily_col I'm pretty sure it's in the documentation of the appropriate jQuery function. Commented Nov 7, 2014 at 11:46
  • 1
    $(element) returns a jQuery object that wraps the DOM element. api.jquery.com/jquery Commented Nov 7, 2014 at 11:46

2 Answers 2

5

You need to understand how jQuery actually works. I will try to explain it briefly.

$ is nothing but a normal javascript function. jQuery === $, is just a function with a fancy name. This function does a lot of different things, depending on what you pass in it. For example if you pass a string it will be treated as CSS selector and jQuery internals will try to find corresponding DOM elements. Or if you pass a string starting with < and ending with > jQuery will create a new DOM element by provided HTML string.

Now if you pass a DOM element or NodeCollection of DOM elements, it/they will be wrapped into jQuery instances so that they can have a jQuery prototype methods. There are many prototype methods jQuery offers. For example text, css, append, attr - those are all methods of jQuery prototype. They are defined basically like this (simplified):

jQuery.prototype.text = function() { ... }

Normal DOM elements don't have those convenient methods jQuery provides. And inside of methods like map or each if you check this value or element parameter like you do, you will see that they are actually not jQuery instances:

element instanceof jQuery // => false

and of course you can't use instance methods with not an instance.

So in order to use jQuery prototype methods you need have a jQuery instance, which you can obtain if you call jQuery function with DOM element passed in it:

$(element) instanceof jQuery // true
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Is there further documentation I can read about this stuff? It seems to be implied that you will know all this stuff in advance.
I would recommend to go through jQuery learning center. And also to get familiar with native javascript prototypical inheritance concepts.
1

Javascript is a programming language.

jQuery is a JavaScript Library.

With jQuery:

$("some element")

In native JavaScript you would have to do something like this.

getElementById('elementByID')

Explained in detail here: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById

MDN is a great resource for beginners. https://developer.mozilla.org/en-US/docs/Web/JavaScript

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.