How does JavaScript know where an element is the DOM? - javascript

I was writing some code in jQuery, like:
$(".middleContent").not(this).slideUp();
(this = currently active .middleContent element)
And I was wondering how JavaScript knew the elements index in the DOM.
I know each object is unique, but if you have a few elements with the same class how does it distinguish between them? It is to do which its index in the tree of all the elements, like how a program has an address in RAM?

Each dom element is an individual object and unique. The not does comparisons on the current execution context ( this ) to make sure that any element inside the array doesnt equal this.

I think you're underestimating what it means for a DOM element to be unique. It's not only the class, tag name or index within the current parent element that identifies a DOM element. Each DOM element internally has a unique identifier, which is not accessible to you. It's used by the browser to organize the DOM internally. There can be hundreds of seemingly identical <div class="middleContent" /> elements in your page, each single one has a unique internal identifier. If you compare one DOM element to another, the browser will always be able to tell whether it's the same element or one that just looks like it.
this refers to one specific DOM element, therefore jQuery is able to filter it out of a collection of seemingly similar elements.

The elements in the DOM are just objects themselves, organised into a tree structure, so they have next and previous siblings at the same level, their own list of children, a parent. From this you can walk around the structure of the tree and manipulate it.
You can obtain the object(s) inside a jQuery object by using indexing notation:
var caption = $('#caption');
var domElement = caption[0];
Then domElement will contain one of these.

Related

How do I use JQuery to iterate a form from the bottom to the top, most nested element first without knowing the id of the deepest element beforehand?

I have a dynamic form builder that create a form in an MVC web application.
It's arranged into sections and questions, sections contain questions or other sections.
The plan was to have some sections open based on the input of certain questions (so for instance checking a box saying you own a car makes the section on car details enabled). All sections which could be opened need to start disabled/hidden (so they can be opened on the relevant input).
All sections and questions have an id although unfortunately I won't know what these are until the page is loaded as Id's are generated dynamically, so i can't just start iterating up from a known deepest element, I have to find it first and then iterate..
I have no idea how to iterate through from the bottom up up, deepest first.
If I iterate from top to bottom, any nested openable sections within openable won't get disabled as the parent will be deactivated before it can be.
Help would be VERY MUCH appreciated.
Thank you.
Did you take a look at JQuery's closest() function?
Example:
function openParent(jq_element) {
jq_element.show();
if(jq_element.parent().length) {
openParent(jq_element.closest());
}
}
$('input').each(function() {
openParent($(this));
});
You could also try something with the parents() function, you can find the differences on the JQuery documentation pages:
.closest()
Begins with the current element
Travels up the DOM tree until it finds a match for the supplied
selector
The returned jQuery object contains zero or one element for each
element in the original set, in document order
.parents()
Begins with the parent element
Travels up the DOM tree to the
document's root element, adding each ancestor element to a temporary
collection; it then filters that collection based on a selector if
one is supplied
The returned jQuery object contains zero or more
elements for each element in the original set, in reverse document
order
UPDATE
To find the most deepest element, you could iterate over all elements that don't have a child element (so all 'deepest' elements):
$('body *:not(:has("*"))');
If you need to open sections based on checkboxes that are checked or not (like your own a car example) You could do something like this:
$('input:checkbox:checked').each(function () {
$( '#' + $(this).data('referenced-section-id-from-current-element') ).show();
});

Grabbing a class within a class with javascript

Hello this is my first question and I'm an amateur developer so forgive me in advance. I'm trying to grab this specific instance of the value class. The website I am working on has hundreds of different values associated with the value class.
<li class = "vin">
<strong class = "title">VIN:</strong>
<span class="value">121212121212121212</span>
</li>
Below is what I've been doing and it hasn't been working.
var vinNum = document.getElementsByClassName('li.vin','span.value');
console.log(vinNum.innerText);
Thank you
Although the existing answers cover the "modern" way to do this already - you can use most of the getElementsBy... (all, I think - was gonna say except getElementById, but that is named in singular for a reason, and because of the meaning of an id special) methods on all elements.
https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName:
The Element.getElementsByClassName() method returns a live HTMLCollection containing all child elements which have all of the given class names. When called on the document object, the complete document is searched, including the root node.
So you can use that twice, to first select an element with one specific class, and then another with a different class "within it", among the descendants of the former. (Not "child elements", as the quoted MDN reference wrongly puts it.)
var vinNumContainer = document.getElementsByClassName('vin')[0],
vinNumElement = vinNumContainer.getElementsByClassName('value')[0];
(Necessary checks for whether elements exist before accessing them, what to do if more than one element (of either one) exists, etc., left out for brevity ;-)
But a simple call to querySelector is of course a quicker way to do it.
Try
var vinNum = document.querySelector('li.vin span.value');
console.log(vinNum.innerText);
This works because rather than selecting by class you're selecting the li.vin element which has a span.value as a child. vinNumber is now a node element. When you call vinNum.innerText you should get the correct number. When you console.log(vinNum) in uour example you will most likely see undefined or the incorrect element.
You can use the document.querySelector function in order to search elements on your page based on class, ID, or anything else that can be selected using a CSS selector.
Using Mozilla's CSS Selector reference, we can see that the CSS selector syntax to select an element which is a direct child of some other element is A > B, where A is a selector matching the parent, and B is a selector matching the child.
So one way to do this is to use:
var vinNum = document.querySelector('li.vin > span.value')
The one-liner above will match the first span element of class value which is a child of a li element of class vin.
However, if you have multiple examples of this structure (a li of class vin with a span of class value within it), using this selector won't work. In fact, if you want to have access to each specific span of class value individually, perhaps the best way would be to add a unique id attribute to each of them.
If your structure looked like this:
<li class = "vin">
<strong class = "title">VIN:</strong>
<span class="value" id="v25">121212121212121212</span>
</li>
You could then use the following:
var vinNum = document.querySelector('#v25')
One last alternative for when you have a list of nested HTML elements all with the same structure is to use document.querySelectorAll, which will return all DOM nodes which match your query and allow you to use JavaScript to run through them and select the values you want.

jquery dom number

I have two duplicate pieces of code that I want to work independently. I am therefore using the unique dom number to manipulate each.
I know I can use $("*").index(this) to get the DOM number of the current element, but how would I go about getting the DOM number of a parent (with class called 'test') of the current element?
Thanks for any help.
You can use $(this).parent() to obtain the parent of the current element, so you could replace "this" with the value of this query and would result something like: $("*").index($(this).parent()[0])

Accessing HTML elements by their id from an array of elements in Javascript is not working

I am trying to access HTML elements by their id from an array of HTML Elements. I created this array using the getElementsByTagName and I am trying to access these elements like this: arrayName.getElementById("theId").
Basically this is what I am trying to implement:
In a Javascript function triggered by an onchange event I receive the reference to the element causing the trigger. Since its a table structure I get the reference to a <td> element.
Now I want to access all the other elements of the <tr> in which that <td> is, using the id of each individual element.
A small replica of my code:
function chngFunction(theTd){
var thisRow = theTd.parentNode;
var inputs = thisRow.getElementsByTagName("input");
alert(inputs[0].value);///////////Currently what I am doing////
alert(inputs[1].value);///////////Currently what I am doing////
.
.
.
//////// What I would like ////////
//// alert(thisRow.getElementById("myId").value); // or something like that////
/////////////// OR ///////////////
//// alert(inputs[].getElementById("myId").value); // or something like that////
///////////////////////////////////
This is what I want because, currently if I make any structural changes to my jsp, I have to make changes to js also (that can leave bugs). So using ids to access individual elements would be great.
Please help me out.
By definition, id values are unique throughout the entire document. So there is no HTMLElement#getElementById that retrieves elements by ID from only that element's descendants. Instead, there's document.getElementById that looks for them globally (since, again, id values are globally unique in the document). So if you're using id values:
alert(document.getElementById("myId").value);
You could use querySelector API.
This should work:
thisRow.querySelector('#myId');
And if your element ids are unique across the document (as they should be), you can just do document.getElementById.
getElementById is a method of the document object, not nodes, so you must use it this way: document.getElementById('id'); .
of course, this will only work if the HTML elements are attached to the DOM tree. In case they are'nt, you should use a selector API. like Sergio is suggesting in his answer.

Some questions about how jquery selectors traverse the dom

How do I know what traverses the DOM and what doesn't?
$('div p')
It seems like this returns all the div elements AND THEN does another scan for P elements on each dom element that was returned in the first div search.
$('div .foo')
The class ones don't seem to scan the dom. They only filter the previous list $('div') for elements that contain classes foo. If a child of $('div') has class foo it is not selected.
$('div, div')
Doesn't contain dupes. So it seems to be scanning only once with a list of lambdas that either compare or they don't. But this gets really really confusing when you have filters like :contains('x') which seem like they can recurse the dom on their very own.
So how do these selectors work? Does 'div .foo' traverse for only divs first and then do a filter for classes that contain foo, or does it somehow get turned into a computation that says when tag==Div && class==foo. What about when there's multiple selectors? They show up in the order they appeared on the page without dupes making me feel like it only scanned the dom once. Maybe it just sorts and removes dupes before returning?
jQuery optimises it's selectors based on what is quickest. If there is a native browser supported method for getting an element (getElementById etc) it will use it, otherwise it will filter based on the results of the natively supported methods.

Categories

Resources