getElementById() wildcard - javascript

I got a div, and there i got some childnodes in undefined levels.
Now I have to change the ID of every element into one div. How to realize?
I thought, because they have upgoing IDs, so if the parent is id='path_test_maindiv' then the next downer would be 'path_test_maindiv_child', and therefore I thought, I'd solve that by wildcards, for example:
document.getElementById('path_test_*')
Is this possible? Or are there any other ways?

Not in native JavaScript. You have various options:
1) Put a class and use getElementsByClassName but it doesn't work in every browser.
2) Make your own function. Something like:
function getElementsStartsWithId( id ) {
var children = document.body.getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substr(0, id.length) == id)
elements.push(child);
}
return elements;
}
3) Use a library or a CSS selector. Like jQuery ;)

In one of the comments you say:
(...) IE is anyway banned on my page, because he doesn't get it with CSS. It's an admin tool for developer, so only a few people, and they will anyway use FF
I think you should follow a different approach from the beginning, but for what it's worth, in the newer browsers (ok, FF3.5), you can use document.querySelectorAll() with which you can get similar results like jQuery:
var elements = document.querySelectorAll('[id^=foo]');
// selects elements which IDs start with foo
Update: querySelectorAll() is only not supported in IE < 8 and FF 3.0.

jQuery allows you to find elements where a particular attribute starts with a specific value
In jQuery you would use
$('[id^="path_test_"]')

Try this in 2019 as a wildcard.
document.querySelectorAll("[id*=path_test_]")

I don't think so wildcards are allowed in getelementById.
Instead you can have all the child nodes of your respective DIV using:
var childNodeArray = document.getElementById('DIVID').childNodes;
This'll give you an array of all elements inside your DIV. Now using for loop you can traverse through all the child elements and simultaneously you can check the type of element or ID or NAME, if matched then change it as you want.

You should not change ID of element to ID of other existing element. It's very wrong, so you better re-think your core logic before going on.
What are you trying to do exactly?
Anyway, to get all elements with ID starting with something, use jQuery as suggested before, if you can't it's also possible using pure JavaScript, let us know.

Related

How to select multiple ID's in a badly designed webpage?

I am maintaining a complex web application.
I have a large number of divs which all have the same ID.
I know this is totally wrong, and as a matter of fact document.getElementById() with that id is going to only produce one match for me.
However I am able to pull out the element that I'm looking for using jQuery (we are on 1.6.2), like this: $('#bad_id[nonstandard_attr_name=somethingSpecific]')
Not quite ready to say that this is a "solution".
I'm worried about whether this is reliable or not. Is jQuery really actually gonna search through all the elements that match the ID using a DOM walk? That's probably the only way to get all of them.
Does it filter elements by the other attribute first, and then filter it down by the ID? That would achieve the desired behavior as well, but it would be good to know the order it does this in.
If you need to select multiple elements with same id you can simply use an attribute selector:
$( "[id='myid']" )
The attribute selector doesn't look at the attribute key for any semantics like unique ids or such.
http://jsfiddle.net/ZWm3G/
I cannot tell you what jQuery or other dom traversals will do (doubtful it will work always) but you can try this :
document.filter = function(attr, val, r) {
r = r || document.getElementsByTagName("*");
var s = [];
for(var i = 0; i < r.length; i++) {
if(r[i].getAttribute(attr) == val) {
s.push(r[i]);
}
}
return s;
};
var s = document.filter("nonstandard_attr_name", "somethingSpecific", document.filter("id", "bad_id"));
console.log(s);
http://jsfiddle.net/KGPFf/1/
Well, as seen in comments, my guess was why would it go on searching for any element. Yes
getElementById returns the first element and then stops searching, but the same doesn't look right for jQuery. It does return all the elements with that "bad" id.
As can be seen in this Fiddle,
So it is selecting all the elements, this means jQuery doesn't stop at the first element, but goes on searching the entire doument, hence IMO, you may use jQuery to select multiple elements with the common id. There shouldn't be any problem.
Use a selector that will result in something other than getElementById() being used should result in consistent results, but make sure you test it with IE8 since IE8 doesn't use document.querySelectorAll().
Using methods such as .find .children and .filter should also yield consistent results regardless of the id being unique.
Sample: http://jsfiddle.net/gb3Mz/

How to remove all elements of a certain class from the DOM?

var paras = document.getElementsByClassName('hi');
for (var i = 0; i < paras.length; i++) {
paras[i].style.color = '#ff0011';
// $('.hi').remove();
}
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p>not class 'hi'</p>
In jQuery, this would be very easy: $('.hi').remove();. I want to learn JS, and then jQuery.
I am stuck and Google has not provided. I do not want to become a copy/paste jQuery programmer. I am just starting to learn JS. Thanks.
To remove an element you do this:
el.parentNode.removeChild(el);
MDN is a great reference. Here are a few relevant pages:
Node
parentNode
removeChild
However you'll run into issues if you loop like that since getElementsByClassName returns a live list, when you remove a node the element is removed from the list as well so you shouldn't increment or you will end up skipping every other element. Instead just continually remove the first element in the list, until there is no first element:
var paras = document.getElementsByClassName('hi');
while(paras[0]) {
paras[0].parentNode.removeChild(paras[0]);
}​
IMO jQuery is great at showing you what is possible to do in Javascript. I actually recommend that after about a week or two of plain JS you learn jQuery, get good at it, and remember what it's abstracting away. One day when you have an excellent grasp of Javascript scoping, objects, and such which you can obtain while using jQuery, go back and try learning how to interact better with the DOM without a library. That way you'll have an easier time learning plain JS and you'll appreciate the abstraction that libraries can provide you even more, while learning that when you only need one or two things a library provides you may be able to write them yourself without including the entire library.
Simple ES6 answer:
document.querySelectorAll('.classname').forEach(e => e.remove());
Explanation:
document.querySelectorAll() loops through the elements in the document returning a NodeList of all elements with the specified selector (e.g. '.class', '#id', 'button')
forEach() loops through the NodeList and executes the specified action for each element
e => e.remove() removes the element from the DOM
Note, however, that this solution is not supported by Internet Explorer. Then again, nothing is.
[].forEach.call(document.querySelectorAll('.hi'),function(e){
e.parentNode.removeChild(e);
});
Here I'm using Array.prototype.forEach to easily traverse all elements in an array-like object, i.e. the static NodeList returned by querySelectorAll, and then using removeChild() to remove the item from the DOM.
For older browsers that don't support querySelectorAll() or forEach():
var classMatcher = /(?:^|\s)hi(?:\s|$)/;
var els = document.getElementsByTagName('*');
for (var i=els.length;i--;){
if (classMatcher.test(els[i].className)){
els[i].parentNode.removeChild(els[i]);
}
}
Note that because getElementsByTagName returns a live NodeList, you must iterate over the items from back to front while removing them from the DOM.
There are also some older browsers that don't support querySelectorAll but that do support getElementsByClassName, which you could use for increased performance and reduced code.
Afaik only a parent can remove a child in native JS. So you would first have to get that elements parent, then use the parent to remove the element. Try this:
var parent = paras[i].parentNode;
parent.removeChild(paras[i]);

How should I define a recurring HTML element & find them all with JavaScript?

I've been trying to work out the best way to define a certain element, which is present an arbitrary number of times throughout a page, without requiring:
the 'name' attribute; or
definition of a new element (XHTML).
I am essentially after the 'name' attribute; however, it appears redundant, obsolete and depreciated in parts.
I am hoping to isolate and manipulate said elements using JavaScript, and preferably avoiding jQuery. Is there a reasonable solution? So far I've thought of:
iterating through all elements with a certain tag and checking for a specific className; or
using incremental IDs on the elements (e.g. el1, el2, el3) and iterating through the sequence until getElementById returns null (feels botchy and only sort of what I'm after).
Thanks :)
querySelectorAll returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors. The object returned is a NodeList.
Reference: https://developer.mozilla.org/en/DOM/Document.querySelectorAll
You can use querySelectorAll, and this is an example you can run in javascript console on this page.
var myList = document.querySelectorAll("a");
for (var c= 0 ; c < myList.length; c += 1) {
console.log(myList[c]);
myList[c].onmouseover= function () {alert(this)}
}
If your reference to a className is deliberate, you could use document.getElementsByClassName(), though this isn't supported by IE 8 and earlier. You could fall back on one of your other techniques for those versions. FWIW, I believe this is how jQuery does it.
You can use className - document.getElementsByClassName()
In HTML 5 you can use data attribute - document.querySelectorAll('[...]');

How to get class name through JavaScript

How do I get the class name through JavaScript given no id with this span.
Like: <span class="xyz"></span>
I want to change the background color of this span.
How can I solve this? Please help me.
tympanus.net/Tutorials/CSS3PageTransitions/index3.html#contact
Something like this should work:
var spans = document.getElementsByTagName("span");
for (var i = 0; i < spans.length; i++) {
if (spans[i].className == 'xyz') {
spans[i].style.backgroundColor = '#000';
}
}
You have the following choices:
Use document.getElementsByClassName("xyz"). This will return a NodeList (like an array) of objects that have that class name. Unfortunately, this function does not exist in older versions of IE.
Use document.getElementsByTagName("span") and then loop over those objects, testing the .className property to see which ones have the desired class.
Use document.querySelectorAll(".xyz") to fetch the desired objects with that class name. Unfortunately this function does not exist in older browsers.
Get a library that automatically handles all CSS3 selector queries in all browsers. If you want just a selector library, then you can use Sizzle. If you want a more comprehensive library for manipulating the DOM, then use YUI3 or jQuery (both of which have Sizzle built-in).
As of 2011, my advice is option #4. Unless this is a very small project, your development productivity will improve immensely by using a CSS3 selector library that has already been developed for cross-browser use. For example in Sizzle, you can get an array of objects with your class name with this line of code:
var list = Sizzle(".xyz");
In jQuery, you can create a jQuery object that contains a list of objects with that class with this line of code:
var list = $(".xyz");
And, both of these will work in all browsers since IE6 without you having to worry about any browser compatibility.
In more modern times (like 2021), you can use built in document.querySelectorAll() and see fairly rich CSS3 selector support.
You can use document.getElementsByClassName('xyz'). Note: it returns an array a NodeList (thanks to #IAbstractDownvoteFactory) since there can be multiple elements with the same class.
var spans = document.getElementByClassName('xyz');
var i;
for(i=0; i<spans.length; i++) {
spans[i].style.backgroundColor = your_color;
}
You can use a jquery to solve the same issue.
var classname = $(this).attr('class'); //here you will get current class name if its with multiple class split it and take first class.
$("."+classname.split(" ")[0]).css("background-color", "yellow");

how to concatenate two getElementsBy

I have a snippet of code like this:
var profileLinks = new Array();
for (var i = 0; i<searchResult.length; ++i)
{
var profileLink=searchResult[i].getElementsByTagName("a");
profileLinks[i]=profileLink[0].href;
alert(i+1+" of "+searchResult.length+" "+profileLinks[i]);
}
It seems like I should be able to make it more concise by using this:
//alternate construction (why doesn't this work?)
var searchResult = document.getElementsByClassName("f_foto").getElementsByTagName("a");
What's wrong here?
Use querySelectorAll() instead:
var searchResult = document.querySelectorAll(".f_foto a");
IE 8 supports querySelectorAll() but not getElementsByClassName(), so this should give you better compatibility too.
For full compatibility, stick to your original code or use a library like jQuery.
document.getElementsByClassName("f_foto")
returns a selection, therefore you cannot chain functions to it. You need to specify an element directly not a whole selection, for example this would work correctly.
document.getElementsByClassName("f_foto")[0].getElementsByTagName("a");
Because document.getElementsByClassName("f_foto")[0] points to an object and not to a selection of objects.
This is why we have libraries - or even modern browsers. You are looking for the css selector $('.f_foto a') in jQuery, or $$('.f_foto a') in Prototoype/Chrome
You call getElementsByTagName on a node, not an array, which is what is returned by getElementsByClassName.
I believe that getElementsByTagName can only be applied to an element node, but the result of getElementsByClassName is surely going to be a list of nodes. You'll either have to pick one ([0]?) or iterate over the collection (make sure it's not empty!).

Categories

Resources