JQuery select by ID vs document.GetElementByID - javascript

I'm just starting with JQuery and am working through a tutorial vid. At one point the presenters go for javascript instead of a JQuery selector. Just wondering why the javascript getElementById below works fine when passing an object to a function, but the second one doesn't?
Thanks!
// works
addTask(document.getElementById('taskText'), evt);
// doesn't
addTask($('#taskText'), evt);

getElementById() returns a DOM element reference.
jQuery's selector returns a jQuery object. You can get the element reference from the jQuery object using
$('#taskText').get(0);
See http://api.jquery.com/get/

To add to the other answer, regarding the result, if you want to use jQuery (which is easier to read), you can get the dom node directly like so:
addTask($('#taskText')[0], evt);

$('#taskText') returns a jQuery object reference.
document.getElementById('taskText') returns a DOM element reference.
If your addTask() function doesn't know how to convert them to what it needs, then that would be the issue since one of them will need a conversion.
If you want to get the first DOM element reference from the jQuery object, you can do so with this:
$('#taskText').get(0)
So these two should be identical:
$('#taskText').get(0)
document.getElementById('taskText')

Both are not exactly same
document.getElementById('taskText'); //returns a HTML DOM Object
var contents = $('#taskText'); //returns a jQuery Object
var contents = $('#taskText')[0]; //returns a HTML DOM Object
so you have to change it to get HTML Dom Object
addTask($('#taskText')[0], evt);

As #Phil and #jfriend00 have pointed out, document.getElementById('taskText') is a DOM element, and $('#taskText') is a jQuery object. The latter is an object of all DOM elements that match the selector.
Think of it as a zero based array, you could pass in the DOM element by doing this:
addTask($('#taskText')[0], evt);

Related

jQuery - .first() versus [0] element

Using jQuery 3.1.1, why are the results of these two different?
$('dd[data-something]').first().innerText;
^ returns undefined
$('dd[data-something]')[0].innerText;
^ returns valid data
Wouldn't the 0th element of an array also be the .first() element?
Edit: Thanks all, I got it, jQuery object versus DOM element. As the debugger clearly showed before I could delete this :) That's a clear sign its time to call it quits for the day.
Because first returns a jQuery object wrapped around the first raw DOM element in the set (which has no innerText property, but does have that handy text method), and [0] directly accesses that raw DOM element (which does have an innerText property on most browsers).
first() will return a jQuery object which is different from the normal JavaScript object and won't work with native JavaScript APIs, here's a qoute from the official documentation
the .first() method constructs a new jQuery object from the first element in that set.
The second one (index zero) will return a JavaScript object it's almost like calling the element using querySelectorAll()
So if you want to get the text use text() from jQuery and it will work
$('dd[data-something]').first().text('new text'); // this will change the text

Why is innerHTML returning 'undefined'?

I'm trying to catch the "value" inside this div, which is editable:
<div class="editable-div" contentEditable="true">Hey</div>
I figured I could do this simply via JavaScript:
var changedText = $('.editable-div').innerHtml
However, this variable will always return "undefined", which confuses me.
Can someone enlighten me on how to reach this "value"?
It is jQuery - you have to use:
$('.editable-div').html()
A jQuery wrapped object is actually not the raw DOM node, but essentially an array of raw DOM nodes that can be acted upon with jQuery specific methods, such as .html(). If you want to interact with the DOM node, you can retrieve it by either iterating through the list or getting the element of that list if you know which one it is:
$('div').each(function(index, element) {
element.innerHTML // ...
}
$('div').get(0).innerHTML
$('div')[0].innerHTML
Note that while it is "kind of" like an array, in that you can get DOM nodes using the array syntax of $('div')[0], you can't treat it like an array in Javascript. In other words, you can't do this:
$('div').forEach(function(element) {
element.innerHTML
}
innerHtml is used with javascript selector and you are using jQuery. so replace innerHtml with .html() or .text() function.
Use this:
var changedText = $('.editable-div').html();
innerHtml is DOM. try $('.editable-div')[0].innerHtml

getElementById vs $('#element')

Before today, I thought that getElementById and $('#element') accomplished the same thing. However, when I tried the following:
// Assuming I have jQuery imported already
var $scrollHolder = $('#element');
var scrollDiv = document.getElementById("element");
scrollDiv.scrollTop = scrollDiv.scrollHeight;
//$scrollHolder.scrollTop = $scrollHolder.scrollHeight;
The commented line didn't work, and the uncommented line did. Do the two methods listed above return different things, or is there an error in my code? Should the commented line be working? I'm very confused and would appreciate insight. Thank you.
you have to get the DOM element from jQuery Object
$scrollHolder[0].scrollTop = $scrollHolder[0].scrollHeight;
or
.get( index )
$scrollHolder.get(0).scrollTop = $scrollHolder.get(0).scrollHeight;
$('#element'); is jQuery Object. It creates an array of matched Objects . But here you have id-selector so you only get one Object you can refer to the Native DOM object by using array index [index] or using .get(index).
document.getElementById("element"); is a native DOM Object
FYI
jQuery way of doing it.
.scrollTop()
.prop()
$scrollHolder.scrollTop($scrollHolder.prop('scrollHeight'));
$('#id) returns jquery objects which doesn't have native DOM properties and document.getElementById('id') returns you a native DOM element which has scrollTop property.
Note that you can make any DOM element act as jquery object by wrapping it with $( ) and you can make jquery object to DOM element by accessing index.
An other solution is using the correct jQuery-Wrapper for that:
$scrollHolder.scrollTop($scrollHolder.scrollHeight);
JQuery selector method always returns an Array of elements.
So commented line will not return what you expect.

jQuery in console not working properly

I'm using the jQueryify bookmarklet on a page so that I can call jQuery functions from the console. But everytime I invoke a jQuery function on a selected object, I get the error:
"TypeError: jQuery("li")[0].children[0].html is not a function
[Break On This Error] jQuery('li')[0].children[0].html();
I have tried this in FireBug as well as Google Chrome's Webkit console.
You are no longer working with jQuery objects when using square braces.
jQuery("li")[0]
This returns you the 1st li as a DOMElement, not a jQuery object.
jQuery("li")[0].children[0]
This returns the 1st li's 1st child as a DOMElement, not a jQuery object.
.html()
This function only works for jQuery objects. For DOMElements, you can use the .innerHTML property.
I suggest instead of dealing with DOMElements, you should continue working with jQuery objects. Try using this instead:
jQuery('li').eq(0).children().eq(0).html()
It looks like you are trying to call a jQuery function, html, on a DOM object children[0]. Try wrapping that in a jQuery object and then calling html
var temp = jQuery("li")[0].children[0];
var html = jQuery(temp).html();
Check the result of jQuery("li")[0].children[0] , it's a regular DOM object NOT a jQuery object. Without seeing your HTML i can't recommend a better selector but a cheap and dirty fix would be
jQuery(jQuery('li')[0].children[0]).html();
This will convert the DOM object result into a jQuery object which has the .html() function.
Accessing the array elements on the jquery object (using []) returns a DOMElement, which obviously doesn't have jquery's methods. You probably want to use eq() instead.
Try following
jQuery(jQuery("li")[0].children[0]).html();
or better one
jQuery("li:eq(0)").children(':eq(0)').html();
or another one
jQuery("li:eq(0)").children().eq(0).html();
even this one will work
jQuery("li").eq(0).children().eq(0).html();

How i can do this in jQuery? any trick to pass selector instead of jQuery object in $

In JavaScript if I append a child which has an ID to another place then it's removed from original location where they currently are.
In javascript I have an event where I can get selector by using this inside the function
$('.').event(function(){
this
});
This is passed to another function and they work fine. Now I want to pass the clone instead of the object; and remember that this does not have ID.
The old code works by passing this to function as DoSomething(this)
if I make a clone using jQuery clone then I have the jQuery object. So how do I get a reference to this instead of the jQuery object when working with the clone?
var clone = $(this).clone() // this is jQuery object.
//how do I get this out of clone?
if I append a child which has an ID to another place then it's removed from original location where they currently are.
Yes, but the same is true of a child node that doesn't have an id attribute as well. An id is only an easy way for you to get a reference to the Element node object; it makes no difference to DOM insertion of cloning behaviour.
In javascript I have an event where I can get selector by using this inside the function
No, this in an event handler gives you the DOM Element node object, not a selector string. A Node can be turned into a jQuery wrapper around it using $(node) and a selector can be turned into a jQuery wrapper on the list of matching nodes using $(selector) but other than this overloading in the jQuery API they're completely different animals.
To pull a Node back out of a jQuery wrapper you can use the get() method or simple array-like access:
var clonedNode= $(this).clone()[0];
var clonedNode= $(this).clone().get(0);
to taste. (get() has some extra features which you don't need here.)
To get the selector used to create a jQuery wrapper you can use the selector property, but this won't return anything if the wrapper was created from a node object ($(this)) rather than a selector.
$(this).clone().get(0). This will get the first matching DOMElement from the jQUery object.
To get the DOMElement object from a jQuery object use get(0):
var clone = $(this).clone(); // this is jQuery object.
var el = clone.get(0); // this is DOMElement object

Categories

Resources