I have a list of elements, and I want to check whether at least one has the class demo_control
The following code works. Is there a more elegant way?
var a='f_date1,f_date2,f_date3,f_date4,f_field1,f_field2'.split(',');
var flag=false;
var i;
for (i = 0; i < a.length; i++) {
if ($('#'+a[i]).hasClass('demo_control')) {
flag=true;
}
}
The documentation of hasClass says:
Determine whether any of the matched elements are assigned the given class.
So no need to loop explicitly; just select the elements in one go, and apply the method on that selection:
let flag = $('#f_date1,#f_date2,#f_date3,#f_date4,#f_field1,#f_field2').hasClass('demo_control');
This could be a possible elegant solution
const ids = 'f_date1,f_date2,f_date3,f_date4,f_field1,f_field2';
const query = ids.split(',').map(el => `#${el}.demo_control`).join(', ');
const flag = $(query).length > 0;
What I've done is just created a single selector for you ids with class. And check if there are any elementa matching this selector.
If demo_control is unique to these fields, why not do:
flag = $(".demo_control").length > 0
This is all you need to do to get a class count...
flag=document.getElementsByClassName('demo_control').length>0;
I would like to write a JS generic function that can process indifferently a single element selected by its ID or multiple element selected by class.
var el1 = document.getElementById('myId');
myFunction(el1)
var el2 = document.getElementsByClassName('myClass');
myFunction(el2)
My problem is to write the function. I started something like:
function myFunction(el) {
if (typeof el == undefined) process(el);
else {
for (let i=0 ; i<el.length ; i++)
process(el[i]);
}
}
I'm not really confident in this solution:
not sure about the test (typeof ... == undefined)
not sure about the loop, map should probably be a better option
Since this should be something commonly used, I'm convinced that some of you has already think to the best way to write this code.
You can probably just accomplish this via a wrapper for the querySelectorAll() function, which is a built-in function used to easily query the DOM:
function myFunction(selector) {
return document.querySelectorAll(`#${selector}`) || document.querySelectorAll(`.${selector}`);
}
This will return a NodeList of the matching elements (first checking for a given id attribute and if that fails, attempting to find any elements sharing the same name as a class attribute).
So if you wanted to perform some process, you could simply throw an iterator on the result if one exists and perform it against each element:
function myFunction(selector) {
let nodes = document.querySelectorAll(`#${selector}`) || document.querySelectorAll(`.${selector}`);
if(nodes) {
for (var i = 0, i < nodes.length; i++) {
process(nodes[i]);
}
}
}
Example
function myFunction(selector) {
return document.querySelectorAll(`#${selector}`) || document.querySelectorAll(`.${selector}`);
}
<div id='id'>id</div>
<div class='class'>class</div>
<br />
<button onclick='alert(myFunction("id"));'>Find By ID</button>
<button onclick='alert(myFunction("class"));'>Find By Class</button>
I'm creating a button that I should highlight certain words within a specified class, but I am having issues with it returning all elements within the class. It will only work if I specify an index, so I'm assuming there may be something wrong with the existing "for loop". Any help is appreciated!
This will work, but only "highlights" the first element in the class, of course:
var bodyText = document.getElementsByClassName('test')[0].innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test')[0].innerHTML = bodyText;
return true;
This will not work at all:
var bodyText = document.getElementsByClassName('test').innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test').innerHTML = bodyText;
return true;
If you want to replace multiple words in multiple elements, you need two loops:
const testElements = document.getElementsByClassName('test');
for (const element of testElements) {
for (const search of searchArray) {
element.innerHTML = doHighlight(element.innerHTML, search, highlightStartTag, highlightEndTag);
}
}
As you can see getElementsByClassName is pluralized (Elements). Indeed a same class can be assigned to multiple HTML elements. You won't find any way to ommit the [0] and you shouldn't anyway as it might mean you're getting data from the wrong node. If you need data from a specific element that you can ensure is unique then you need to give it an id and use getElementById instead.
You cannot access innerHTML in something which returns an htmlcollection
document.getElementsByClassName('test').innerHTML
Because it's written in plain english: getElementsByClassName. plural.
"Elements".
with an "s" at the end...
meaning it's a (sort of) Array (an htmlcollection)
There are two similar classes - 'item' and 'item one'
When I use document.getElementsByClassName('item') it returns all elements that match both classes above.
How I can get elements with 'item' class only?
The classname item one means the element has class item and class one.
So, when you do document.getElementsByClassName('item'), it returns that element too.
You should do something like this to select the elements with only the class item:
e = document.getElementsByClassName('item');
for(var i = 0; i < e.length; i++) {
// Only if there is only single class
if(e[i].className == 'item') {
// Do something with the element e[i]
alert(e[i].className);
}
}
This will check that the elements have only class item.
Live Demo
document.querySelectorAll('.item:not(.one)');
(see querySelectorAll)
The other way is to loop over the what document.getElementsByClassName('item') returns, and check if the one class is present (or not):
if(element.classList.contains('one')){
...
}
You're going to want to make your own function for exact matches, because spaces in a class means it has multiple classes. Something like:
function GetElementsByExactClassName(someclass) {
var i, length, elementlist, data = [];
// Get the list from the browser
elementlist = document.getElementsByClassName(someclass);
if (!elementlist || !(length = elementlist.length))
return [];
// Limit by elements with that specific class name only
for (i = 0; i < length; i++) {
if (elementlist[i].className == someclass)
data.push(elementlist[i]);
}
// Return the result
return data;
} // GetElementsByExactClassName
You can use Array.filter to filter the matched set to be only those with class test:
var elems = Array.filter( document.getElementsByClassName('test'), function(el){
return !!el.className.match(/\s*test\s*/);
});
Or only those with test but not one:
var elems = Array.filter( document.getElementsByClassName('test'), function(el){
return el.className.indexOf('one') < 0;
});
(Array.filter may work differently depending on your browser, and is not available in older browsers.) For best browser compatibility, jQuery would be excellent for this: $('.test:not(.one)')
If you have jQuery, it can be done using the attribute equals selector syntax like this: $('[class="item"]').
If you insist on using document.getElementsByClassName, see the other answers.
doStuff(document.getElementById("myCircle1" "myCircle2" "myCircle3" "myCircle4"));
This doesn't work, so do I need a comma or semi-colon to make this work?
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes. You have several different options:
You could implement your own function that takes multiple ids and returns multiple elements.
You could use document.querySelectorAll() that allows you to specify multiple ids in a CSS selector string .
You could put a common class names on all those nodes and use document.getElementsByClassName() with a single class name.
Examples of each option:
doStuff(document.querySelectorAll("#myCircle1, #myCircle2, #myCircle3, #myCircle4"));
or:
// put a common class on each object
doStuff(document.getElementsByClassName("circles"));
or:
function getElementsById(ids) {
var idList = ids.split(" ");
var results = [], item;
for (var i = 0; i < idList.length; i++) {
item = document.getElementById(idList[i]);
if (item) {
results.push(item);
}
}
return(results);
}
doStuff(getElementsById("myCircle1 myCircle2 myCircle3 myCircle4"));
This will not work, getElementById will query only one element by time.
You can use document.querySelectorAll("#myCircle1, #myCircle2") for querying more then one element.
ES6 or newer
With the new version of the JavaScript, you can also convert the results into an array to easily transverse it.
Example:
const elementsList = document.querySelectorAll("#myCircle1, #myCircle2");
const elementsArray = [...elementsList];
// Now you can use cool array prototypes
elementsArray.forEach(element => {
console.log(element);
});
How to query a list of IDs in ES6
Another easy way if you have an array of IDs is to use the language to build your query, example:
const ids = ['myCircle1', 'myCircle2', 'myCircle3'];
const elements = document.querySelectorAll(ids.map(id => `#${id}`).join(', '));
No, it won't work.
document.getElementById() method accepts only one argument.
However, you may always set classes to the elements and use getElementsByClassName() instead. Another option for modern browsers is to use querySelectorAll() method:
document.querySelectorAll("#myCircle1, #myCircle2, #myCircle3, #myCircle4");
I suggest using ES5 array methods:
["myCircle1","myCircle2","myCircle3","myCircle4"] // Array of IDs
.map(document.getElementById, document) // Array of elements
.forEach(doStuff);
Then doStuff will be called once for each element, and will receive 3 arguments: the element, the index of the element inside the array of elements, and the array of elements.
getElementByID is exactly that - get an element by id.
Maybe you want to give those elements a circle class and getElementsByClassName
document.getElementById() only takes one argument. You can give them a class name and use getElementsByClassName() .
Dunno if something like this works in js, in PHP and Python which i use quite often it is possible.
Maybe just use for loop like:
function doStuff(){
for(i=1; i<=4; i++){
var i = document.getElementById("myCiricle"+i);
}
}
Vulgo has the right idea on this thread. I believe his solution is the easiest of the bunch, although his answer could have been a little more in-depth. Here is something that worked for me. I have provided an example.
<h1 id="hello1">Hello World</h1>
<h2 id="hello2">Random</h2>
<button id="click">Click To Hide</button>
<script>
document.getElementById('click').addEventListener('click', function(){
doStuff();
});
function doStuff() {
for(var i=1; i<=2; i++){
var el = document.getElementById("hello" + i);
el.style.display = 'none';
}
}
</script>
Obviously just change the integers in the for loop to account for however many elements you are targeting, which in this example was 2.
The best way to do it, is to define a function, and pass it a parameter of the ID's name that you want to grab from the DOM, then every time you want to grab an ID and store it inside an array, then you can call the function
<p id="testing">Demo test!</p>
function grabbingId(element){
var storeId = document.getElementById(element);
return storeId;
}
grabbingId("testing").syle.color = "red";
You can use something like this whit array and for loop.
<p id='fisrt'>??????</p>
<p id='second'>??????</p>
<p id='third'>??????</p>
<p id='forth'>??????</p>
<p id='fifth'>??????</p>
<button id="change" onclick="changeColor()">color red</button>
<script>
var ids = ['fisrt','second','third','forth','fifth'];
function changeColor() {
for (var i = 0; i < ids.length; i++) {
document.getElementById(ids[i]).style.color='red';
}
}
</script>
For me worked flawles something like this
doStuff(
document.getElementById("myCircle1") ,
document.getElementById("myCircle2") ,
document.getElementById("myCircle3") ,
document.getElementById("myCircle4")
);
Use jQuery or similar to get access to the collection of elements in only one sentence. Of course, you need to put something like this in your html's "head" section:
<script type='text/javascript' src='url/to/my/jquery.1.xx.yy.js' ...>
So here is the magic:
.- First of all let's supose that you have some divs with IDs as you wrote, i.e.,
...some html...
<div id='MyCircle1'>some_inner_html_tags</div>
...more html...
<div id='MyCircle2'>more_html_tags_here</div>
...blabla...
<div id='MyCircleN'>more_and_more_tags_again</div>
...zzz...
.- With this 'spell' jQuery will return a collection of objects representing all div elements with IDs containing the entire string "myCircle" anywhere:
$("div[id*='myCircle']")
This is all! Note that you get rid of details like the numeric suffix, that you can manipulate all the divs in a single sentence, animate them... Voilá!
$("div[id*='myCircle']").addClass("myCircleDivClass").hide().fadeIn(1000);
Prove this in your browser's script console (press F12) right now!
As stated by jfriend00,
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes.
However, here's some example code I created which you can give one or a comma separated list of id's. It will give you one or many elements in an array. If there are any errors, it will return an array with an Error as the only entry.
function safelyGetElementsByIds(ids){
if(typeof ids !== 'string') return new Error('ids must be a comma seperated string of ids or a single id string');
ids = ids.split(",");
let elements = [];
for(let i=0, len = ids.length; i<len; i++){
const currId = ids[i];
const currElement = (document.getElementById(currId) || new Error(currId + ' is not an HTML Element'));
if(currElement instanceof Error) return [currElement];
elements.push(currElement);
};
return elements;
}
safelyGetElementsByIds('realId1'); //returns [<HTML Element>]
safelyGetElementsByIds('fakeId1'); //returns [Error : fakeId1 is not an HTML Element]
safelyGetElementsByIds('realId1', 'realId2', 'realId3'); //returns [<HTML Element>,<HTML Element>,<HTML Element>]
safelyGetElementsByIds('realId1', 'realId2', 'fakeId3'); //returns [Error : fakeId3 is not an HTML Element]
If, like me, you want to create an or-like construction, where either of the elements is available on the page, you could use querySelector. querySelector tries locating the first id in the list, and if it can't be found continues to the next until it finds an element.
The difference with querySelectorAll is that it only finds a single element, so looping is not necessary.
document.querySelector('#myCircle1, #myCircle2, #myCircle3, #myCircle4');
here is the solution
if (
document.getElementById('73536573').value != '' &&
document.getElementById('1081743273').value != '' &&
document.getElementById('357118391').value != '' &&
document.getElementById('1238321094').value != '' &&
document.getElementById('1118122010').value != ''
) {
code
}
You can do it with document.getElementByID Here is how.
function dostuff (var here) {
if(add statment here) {
document.getElementById('First ID'));
document.getElementById('Second ID'));
}
}
There you go! xD