A few questions about JavaScript basics - $, "is not a function" - javascript

Being fully self-taught without actually reading up on JavaScript (It's my job now, believe it or not) there are a few things I accept but don't understand.
The first one is the dollar sign.
As far as I use understand it, it's a shortcut to document.getElementById(),
but if I log $ and document.getElementById() to console - Only $ returns a value. This value however is always function(), shouldn't it be. The element? What gives?
The second issue I have is something that keeps coming up in my code and I go out of my way to change the code to eliminate it. It's the "... is not a function" error.
For example:
if ($.inArray($(div_id).val(), arr) >= 0);
Will give the error .val() is not a function. Why? And how do I use the value of div_id to see if it's in array?

Hiya. When you're using Jquery (which I assume you are), then $ will return the jquery object. This can contain an array of matched HTML elements depending on the selector you used. For example $("#foo") will return the jquery object containing the element with id foo. You can get the actual HTML DOM element out using $("#foo")[0] - using the array-style notation.
Can you give us some more info on what you're trying to achieve with the $.inArray example?

$ is a valid variable name.
So if you try to use $ without setting it, it will not work.
A lot of people/frameworks however use $ as a shortcut to document.getElementById, they would declare it at the top of the script as:
function $(id) { return document.getElementById(id); }

$ and document.getElementById is not one of the same thing. $ gives you a function in console only when you are using some library like jquery which mapes $ to a function.
.val id primarly used to get value of the form elements and that is a jquery function. I think you need to learn more around javascript and jQuery

Neither Javascript nor the DOM define $, which (as other answerers said) is often defined in general-purpose DOM libraries like jQuery, Prototype or Mootools. Based on the particular code you included, I suspect you've been coding against the jQuery API (because you use $.inArray, see http://api.jquery.com/jQuery.inArray/; though your claim that $ aliases document.getElementById confuses matters, as jQuery expects CSS selectors rather than element IDs).
When $ is expected but undefined, that usually means you'll need to include the library whose API you're using in the HTML document.

Related

How to print out the final selector in a jQuery method chain

If I have the following jQuery chain
let mpath = $('.wlc2022.confirm').find('.something');
how can I print out ".something" or "something" (in either jQuery or raw JavaScript syntax) to the console window because its the last selector that mpath is looking for?
I have tried...
console.log(mpath.val)
console.log(mpath.value)
But nothing so far...
There is no API for that in modern (post-3.0) versions of jQuery. There used to be a .selector property on jQuery objects, but it was removed because it was unreliable.
Note also that mpath itself is not "looking for" anything; it gets the result of the jQuery-based expression. Probably the best way to do what you want would be to construct some sort of utility around that expression pattern, and have it retain that last selector and make it available somehow.

Javascript 'undefined is not a function' - can you clarify this example?

The relevant HTML:
<div id="suggestedEmailDiv">
Did you mean <a class="suggestedEmailClass">
<span id="suggestedEmailAddressSpan" class="address"></span>
#
<span id="suggestedEmailDomainSpan" class="domain"></span>
</a>?
</div>
The relevant javascript:
console.log("suggestion.address ", suggestion.address);
console.log("suggestedEmailAddressSpan ", $('suggestedEmailAddressSpan'));
// here's where it goes wonky:
$('suggestedEmailAddressSpan').text(suggestion.address);
The relevant Logs:
[Log] suggestion.address qwew (btadmin, line 195) <-- suggestion.address has a value
[Log] suggestedEmailAddressSpan (btadmin, line 198) <-- it is a defined span!!
<span id=​"suggestedEmailAddressSpan" class=​"address">​</span>​
[Error] TypeError: undefined is not a function (evaluating '$('suggestedEmailAddressSpan').text(suggestion.address)')
suggested (btadmin, line 205)
responder (prototype.js, line 5597)
I know I am missing something simple but important here... What is it??
Thanks for any help!!
Ok, the closest thing I can think of is that jQuery is not loaded.
What gave it away is that your log didn't return a jQuery object. jQuery returns an array-like object, which on the console appears like a bracketed list of elements. You can verify this by doing $('body') on the console in this StackOverflow page (because SO uses jQuery :P) and you should see something like:
[<body class=​"question-page new-topbar">​…​</body>​]
Now two things may have resulted when jQuery is not loaded:
$ is undefined, resulting in that error.
Some browsers (like Chrome) natively have a $ function which maps to document.querySelector. If jQuery didn't load, the $ global wasn't overridden. The error is because you called text() on the result of querySelector, which is the first DOM element that matches the provided selector.
Another possible situation is that something else has taken over the $ global. Symptoms may include jQuery successfully loaded but $ isn't jQuery. But your logs don't give much clues if this happened.
To solve your problem, make sure jQuery is loaded before your script. In addition, place scripts that operate on the DOM inside a callback to $(document).ready(), that way your scripts operate after the DOM has fully loaded.
In addition, your selector is wrong. ID's selectors start with #. However, providing wrong selectors to jQuery should not make the error since calling a wrong selector will return an empty jQuery set that will still have the .text() method.
you are missing the id selector in your query it should be like this
$("#suggestedEmailAddressSpan") read more about JQuery selector
for selecting Ids use
$('#suggestedEmailAddressSpan')
for class use
$('.suggestedEmailClass')
for jquery it's better to write your codes between ready function:
$(document).ready(function() {
//your code
});

jQuery / JavaScript, why do I need to wrap variables in $() to use them?

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?
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
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

Error in my jquery Code `Uncaught TypeError: Cannot call method 'eq' of null`

Please mention the error in this code.
$("#gridTable tr").eq(1).find('td').forEach( function(){//some code here});
I have tried different selectors but nothing worked.
I also tried using just id of specific row but same error with message that:
Cannot call method find of null.
On:
$("#firstRow").find('td').forEach( function(){//some code here});
In each case, the error is telling you that $("#gridTable tr") returned null.
This suggests you're not using jQuery, but instead Prototype or MooTools (or something else entirely). jQuery's $() function will never return null, but both Prototype and MooTools' $() function will, if they don't find an element with the given ID. If you're using Prototype or MooTools, note that $() doesn't take a selector like jQuery's does, it takes an id. So you wouldn't use the # on it, and couldn't pass in a descendant combinator as you are in your example. (The nearest equivalent in Prototype to jQuery's $ is $$.)
Separately, if you were using jQuery, jQuery objects don't have forEach; they do have each which is similar (but the order of the arguments to your iterator function is different).

document.getElementById vs jQuery $()

Is this:
var contents = document.getElementById('contents');
The same as this:
var contents = $('#contents');
Given that jQuery is loaded?
Not exactly!!
document.getElementById('contents'); //returns a HTML DOM Object
var contents = $('#contents'); //returns a jQuery Object
In jQuery, to get the same result as document.getElementById, you can access the jQuery Object and get the first element in the object (Remember JavaScript objects act similar to associative arrays).
var contents = $('#contents')[0]; //returns a HTML DOM Object
No.
Calling document.getElementById('id') will return a raw DOM object.
Calling $('#id') will return a jQuery object that wraps the DOM object and provides jQuery methods.
Thus, you can only call jQuery methods like css() or animate() on the $() call.
You can also write $(document.getElementById('id')), which will return a jQuery object and is equivalent to $('#id').
You can get the underlying DOM object from a jQuery object by writing $('#id')[0].
Close, but not the same. They're getting the same element, but the jQuery version is wrapped in a jQuery object.
The equivalent would be this
var contents = $('#contents').get(0);
or this
var contents = $('#contents')[0];
These will pull the element out of the jQuery object.
A note on the difference in speed. Attach the following snipet to an onclick call:
function myfunc()
{
var timer = new Date();
for(var i = 0; i < 10000; i++)
{
//document.getElementById('myID');
$('#myID')[0];
}
console.log('timer: ' + (new Date() - timer));
}
Alternate commenting one out and then comment the other out. In my tests,
document.getElementbyId averaged about 35ms (fluctuating from 25ms up to 52ms on about 15 runs)
On the other hand, the
jQuery averaged about 200ms (ranging from 181ms to 222ms on about 15 runs).
From this simple test you can see that the jQuery took about 6 times as long.
Of course, that is over 10000 iterations so in a simpler situation I would probably use the jQuery for ease of use and all of the other cool things like .animate and .fadeTo. But yes, technically getElementById is quite a bit faster.
No. The first returns a DOM element, or null, whereas the second always returns a jQuery object. The jQuery object will be empty if no element with the id of contents was matched.
The DOM element returned by document.getElementById('contents') allows you to do things such as change the .innerHTML (or .value) etc, however you'll need to use jQuery methods on the jQuery Object.
var contents = $('#contents').get(0);
Is more equivilent, however if no element with the id of contents is matched, document.getElementById('contents') will return null, but $('#contents').get(0) will return undefined.
One benefit on using the jQuery object is that you won't get any errors if no elements were returned, as an object is always returned. However you will get errors if you try to perform operations on the null returned by document.getElementById
No, actually the same result would be:
$('#contents')[0]
jQuery does not know how many results would be returned from the query. What you get back is a special jQuery object which is a collection of all the controls that matched the query.
Part of what makes jQuery so convenient is that MOST methods called on this object that look like they are meant for one control, are actually in a loop called on all the members int he collection
When you use the [0] syntax you take the first element from the inner collection. At this point you get a DOM object
In case someone else hits this... Here's another difference:
If the id contains characters that are not supported by the HTML standard (see SO question here) then jQuery may not find it even if getElementById does.
This happened to me with an id containing "/" characters (ex: id="a/b/c"), using Chrome:
var contents = document.getElementById('a/b/c');
was able to find my element but:
var contents = $('#a/b/c');
did not.
Btw, the simple fix was to move that id to the name field. JQuery had no trouble finding the element using:
var contents = $('.myclass[name='a/b/c']);
var contents = document.getElementById('contents');
var contents = $('#contents');
The code snippets are not the same. first one returns a Element object (source).
The second one, jQuery equivalent will return a jQuery object containing a collection of either zero or one DOM element. (jQuery documentation). Internally jQuery uses document.getElementById() for efficiency.
In both the cases if more than one element found only the first element will be returned.
When checking the github project for jQuery I found following line snippets which seems to be using document.getElementById codes (https://github.com/jquery/jquery/blob/master/src/core/init.js line 68 onwards)
// HANDLE: $(#id)
} else {
elem = document.getElementById( match[2] );
Just like most people have said, the main difference is the fact that it is wrapped in a jQuery object with the jQuery call vs the raw DOM object using straight JavaScript. The jQuery object will be able to do other jQuery functions with it of course but, if you just need to do simple DOM manipulation like basic styling or basic event handling, the straight JavaScript method is always a tad bit faster than jQuery since you don't have to load in an external library of code built on JavaScript. It saves an extra step.
One other difference: getElementById returns the first match, while $('#...') returns a collection of matches - yes, the same ID can be repeated in an HTML doc.
Further, getElementId is called from the document, while $('#...') can be called from a selector. So, in the code below, document.getElementById('content') will return the entire body but $('form #content')[0] will return inside of the form.
<body id="content">
<h1>Header!</h1>
<form>
<div id="content"> My Form </div>
</form>
</body>
It might seem odd to use duplicate IDs, but if you are using something like Wordpress, a template or plugin might use the same id as you use in the content. The selectivity of jQuery could help you out there.
All the answers are old today as of 2019 you can directly access id keyed filds in javascript simply try it
<p id="mytext"></p>
<script>mytext.innerText = 'Yes that works!'</script>
Online Demo!
- https://codepen.io/frank-dspeed/pen/mdywbre
jQuery is built over JavaScript. This means that it's just javascript anyway.
document.getElementById()
The document.getElementById() method returns the element that has the ID attribute with the specified value and Returns null if no elements with the specified ID exists.An ID should be unique within a page.
Jquery $()
Calling jQuery() or $() with an id selector as its argument will return a jQuery object containing a collection of either zero or one DOM element.Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM.
All the answers above are correct. In case you want to see it in action, don't forget you have Console in a browser where you can see the actual result crystal clear :
I have an HTML :
<div id="contents"></div>
Go to console (cntrl+shift+c) and use these commands to see your result clearly
document.getElementById('contents')
>>> div#contents
$('#contents')
>>> [div#contents,
context: document,
selector: "#contents",
jquery: "1.10.1",
constructor: function,
init: function …]
As we can see, in the first case we got the tag itself (that is, strictly speaking, an HTMLDivElement object). In the latter we actually don’t have a plain object, but an array of objects. And as mentioned by other answers above, you can use the following command:
$('#contents')[0]
>>> div#contents

Categories