Is it possible to add an HTML ID via the browser console using DOM Manipulation?
For example, suppose I am dealing with the following element:
<div class="elementClass">
I can fetch via DOM with something like:
document.getElementsByClassName("elementClass");
However, is it possible to add an attribute via this type of method? If I inspect the element with chrome I can do it manually, but I am wondering if it's possible to inject that ID via JavaScript.
Thanks!
You can do:
document.getElementsByClassName("elementClass")[0].setAttribute("id", "some ID");
Yes you can modify attributes of an object (HTMLElement) via javascript
getElementsByclassName returns an array, simply iterate through the list and set the attributes you wish.
var elements = document.getElementsByClassName("elementClass");
for(var I = 0; I < elements.length; I++)
element[I].id = "element" + I;
Then you could access any of those elements with that class via
var element = document.getElementById("element" + 0); //Gets First Element
Sure.
document.getElementsByClassName('elementClass')[0].id = 'someID';
or
document.getElementsByClassName('elementClass')[0].setAttribute('id', 'someID');
Just know that if you grab elements using getElementsByClassName then it will return an array of elements (assuming any elements with the matching class exist) so modifying the array won't give you the result you want.
setAttribute() method on the DOM element should work just fine.
HTML
<div class="elementClass">
This is the content of elementClass
</div>
<button onclick="buttonClicked()">Click to add attribute id red to elementClass</button>
Javascript
function buttonClicked(){
document.getElementsByClassName("elementClass")[0].setAttribute("id", "red");
}
CSS
#red {
background-color: red;
}
PLAYGROUND
Note that manipulating the class attribute causes the browser to reflow, therefore it is worth mentioning to use setAttribute() wisely to not cause performance issue.
Related
I am writing a small library where I am in need of selecting a relative element to the targeted element through querySelector method.
For example:
HTML
<div class="target"></div>
<div class="relative"></div>
<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>
<div class="target"></div>
<div class="relative"></div>
JavaScript
var target = document.querySelectorAll('.target')[1];
// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');
In the above example, I am trying to select the .relative class element relative only to the .target element whose value is stored in target variable. No styles should apply to the other .relative class elements.
PS: the selectors can vary. So, I can't use JavaScript's predefined methods like previousElementSibling or nextElementSibling.
I don't need solution in jQuery or other JavaScript libraries.
Well it should be ideally:
var relativeElement = target.querySelector('.relative');
But this will actually try to select something inside the target element.
therefore this would only work if your html structure is something like:
<div class="target">
<div class="relative"></div>
</div>
Your best bet would probably in this case be to use nextElementSibling which I understand is difficult for you to use.
You cannot.
If you insist on using the querySelector of the subject element, the answers is there is no way.
The spec and MDN both says clearly that Element.querySelector must return "a descendant of the element on which it is invoked", and the object element you want does not meet this limitation.
You must go up and use other elements, e.g. document.querySelector, if you want to break out.
You can always override Element.prototype.querySelector to do your biddings, including implementing your own CSS engine that select whatever element you want in whatever syntax you want.
I didn't mention this because you will be breaking the assumption of a very important function, easily breaking other libraries and even normal code, or at best slowing them down.
target.querySelector('.relative');
By using querySelector on the target instead of document, you scope the DOM traversal to the target element.
It is not entirely clear from your explanation, but by related i assume you mean descendant?
To get all target elements you can use
document.querySelectorAll('.target')
And then iterate the result
I found a way which will work for my library.
I will replace "this " in the querySelector with a unique custom attribute value. Something like this:
Element.prototype.customQuerySelector = function(selector){
// Adding a custom attribute to refer for selector
this.setAttribute('data-unique-id', '1');
// Replace "this " string with custom attribute's value
// You can also add a unique class name instead of adding custom attribute
selector = selector.replace("this ", '[data-unique-id="1"] ');
// Get the relative element
var relativeElement = document.querySelector(selector);
// After getting the relative element, the added custom attribute is useless
// So, remove it
this.removeAttribute('data-unique-id');
// return the fetched element
return relativeElement;
}
var element = document.querySelectorAll('.target')[1];
var targetElement = element.customQuerySelector('this + .relative');
// Now, do anything with the fetched relative element
targetElement.style.color = "red";
Working Fiddle
what's the different between using:
// assuming using elements/tags 'span' creates an array and want to access its first node
1) var arrayAccess = document.getElementsByTagName('elementName')[0]; // also tried property items()
vs
// assuming I assign an id value to the first span element/tag
// specifically calling a node by using it's id value
2) var idAccess = document.getElementById('idValue');
then if I want to change the text node....when using example 1) it will not work, for example:
arrayAccess.firstChild.nodeValue = 'some text';
or
arrayAccess.innerText/innerHTML/textContent = 'some text';
If I "access" the node through its id value then it seems to work fine....
Why is it that when using array it does not work? I'm new to javascript and the book I'm reading does not provide an answer.
Both are working,
In your first case you need to pass the tag name instead of the element name. Then only it will work.
There might be a case that you trying to set input/form elements using innerHTML. At that moment you need to use .value instead of innerHTML.
InnerHTML should be used for div, span, td and similar elements.
So your html markup example:
<div class="test">test</div>
<div class="test">test1</div>
<span id="test">test2</span>
<button id="abc" onclick="renderEle();">Change Text</button>
Your JS code:
function renderEle() {
var arrayAccess = document.getElementsByTagName('div')[0];
arrayAccess.innerHTML = "changed Text";
var idEle = document.getElementById('test');
idEle.innerHTML = "changed this one as well";
}
Working Fiddle
When you use document.getElementsByTagName('p'), the browser traverses the rendered DOM tree and returns a node list (array) of all elements that have the matching tag.
When you use document.getElementById('something'), the browser traverses the rendered DOM tree and returns a single node matching the ID if it exists (since html ID's are unique).
There are many differences when to use which, but one main factor will be speed (getElementById is much faster since you're only searching for 1 item).
To address your other question, you already have specified that you want the first element in the returned nodeList (index [0]) in your function call:
var arrayAccess = document.getElementsByTagName('elementName')[0];
Therefore, arrayAccess is already set to the first element in the returned query. You should be able to access the text by the following. The same code should work if you used document.getElementById to get the DOM element:
console.log(arrayAccess.textContent);
Here's a fiddle with an example:
http://jsfiddle.net/qoe30w2w/
Hope this helps!
It is a script in javascript that add a <div></div> and add an id, a class, html.. I want to add name attribut too and my code doesn't works, but I wonder why..
There https://developer.mozilla.org/fr/DOM/element I have seen that element.name = 'newname'; can edit it..
function newgroup() {
var e = document.getElementsByName('group');
var nb = e.length + 1
div = document.createElement("div");
div.id = 'group'+nb;
div.className = 'panel_drop';
div.name = '1';
div.innerHTML = '<h5>Group '+nb+'</h5>';
div.innerHTML += '<div class=\'drop_zone\'></div>';
document.getElementById('groups').appendChild(div);
}
The name attribute of an HTML element is not mapped to the name property of the corresponding DOM element for all elements, but only for certain types of elements, and DIV elements are not one of them.
You can check for which types of HTML elements the name attribute is specified here: http://www.whatwg.org/specs/web-apps/current-work/multipage//section-index.html#attributes-1
Since the HTML standard doesn't specify a name attribute for DIV elements, my recommendation is to not use such an attribute/property on DIV elements. If you need to attach additional information to your DIV elements, consider data-* attributes.
div.setAttribute('name', '1');
The fact that div.getAttribute('class') is also exported as a convenience function as the className property (with an impilicit setter and getter) doesn't mean that it is a consistent way to handle DOM node property names.
BTW, consider using a javascript framework, like jQuery, Prototype, MooTools or YUI, helps on the long run...
For example with Jquery you can have easily a finer control on attributes by changing them or removing them
<body>
<span someAttribute="xyz">.....</span>
...
<div>
...
<span someAttribute="abc">.....</span>
...
<div someAttribute="pqr">.....</div>
...
</div>
</body>
Here is a sample html page.. I need to select the html elements by its attributes i can get the attribute values by getAttribute() but i need to select all the elements first.
How in javascript to get elements which has the attribute name as "someAttribute". Once i get the elements i can get the attribute values and use my function.
Note: i want to do this without using jquery.
In new browsers you can do:
var el = document.querySelector('[someAttribute="someValue"]');
store each element in a array the loop throught each element, and if the element contains the attribute someAttribute do somgthing.
var arr_elms = [];
arr_elms = document.body.getElementsByTagName("*");
var elms_len = arr_elms.length;
for (var i = 0; i < elms_len; i++) {
if(arr_elms[i].getAttribute("someAttribute") != null){
alert("FOUND : " + arr_elms[i].getAttribute("someAttribute"));
}
}
You can select elements by tag name using document.body.getElementsByTagName("div") to get all the div elements inside your document. This function returns an array of elements, which you can parse and filter out elements that don't match your criteria.
You can traver all elements of DOM tree.
you can use
var all = document.getElementsByTagName('*');
but this also returns the html, head and body ...
and then do a loop over all elements and look for the attributes.
I found a snippet called getElementsByAttribute(doc, tagArray, attribute, attributeValue)
You can give a try to a working fiddle: http://jsfiddle.net/Yx7EU/
Hope this can help.
<div onclick="test(this)">
Test
<div id="child">child</div>
</div>
I want to change the style of the child div when the parent div is clicked. How do I reference it? I would like to be able to reference it by ID as the the html in the parent div could change and the child won't be the first child etc.
function test(el){
el.childNode["child"].style.display = "none";
}
Something like that, where I can reference the child node by id and set the style of it.
Thanks.
EDIT: Point taken with IDs needing to be unique. So let me revise my question a little. I would hate to have to create unique IDs for every element that gets added to the page. The parent div is added dynamically. (sort of like a page notes system). And then there is this child div. I would like to be able to do something like this: el.getElementsByName("options").item(0).style.display = "block";
If I replace el with document, it works fine, but it doesn't to every "options" child div on the page. Whereas, I want to be able to click the parent div, and have the child div do something (like go away for example).
If I have to dynamically create a million (exaggerated) div IDs, I will, but I would rather not. Any ideas?
In modern browsers (IE8, Firefox, Chrome, Opera, Safari) you can use querySelector():
function test(el){
el.querySelector("#child").style.display = "none";
}
For older browsers (<=IE7), you would have to use some sort of library, such as Sizzle or a framework, such as jQuery, to work with selectors.
As mentioned, IDs are supposed to be unique within a document, so it's easiest to just use document.getElementById("child").
This works well:
function test(el){
el.childNodes.item("child").style.display = "none";
}
If the argument of item() function is an integer, the function will treat it as an index. If the argument is a string, then the function searches for name or ID of element.
If the child is always going to be a specific tag then you could do it like this
function test(el)
{
var children = el.getElementsByTagName('div');// any tag could be used here..
for(var i = 0; i< children.length;i++)
{
if (children[i].getAttribute('id') == 'child') // any attribute could be used here
{
// do what ever you want with the element..
// children[i] holds the element at the moment..
}
}
}
document.getElementById('child') should return you the correct element - remember that id's need to be unique across a document to make it valid anyway.
edit : see this page - ids MUST be unique.
edit edit : alternate way to solve the problem :
<div onclick="test('child1')">
Test
<div id="child1">child</div>
</div>
then you just need the test() function to look up the element by id that you passed in.
If you want to find specific child DOM element use method querySelectorAll
var $form = document.getElementById("contactFrm");
in $form variable we can search which child element we want :)
For more details about how to use querySelectorAll check this page