Reputation: 6552
Let's assume for a moment that I have something like this:
if (document.getElementById('div1').innerHTML &&
document.getElementById('div2').innerHTML &&
document.getElementById('div3').innerHTML &&
document.getElementById('div4').innerHTML &&
document.getElementById('div5').innerHTML &&
...
document.getElementById('div100').innerHTML)
Obviously typing out and maintaining a big conditional statement like this is problematic.
I would like some solution like:
var conditional = "";
for(var i = 1; i <= 100; i++){
conditional += "document.getElementById('div" + i +"').innerHTML";
if(i < 100) {
conditional += " && ";
}
}
if(interpretStringAsJSExpression(conditional)){
console.log("all my divs have content");
}
Is something like this possible in JavaScript?
Great answers have been submitted, and I am sure that I and others will benefit from them. However, purely from a place of curiosity, is it possible to store and run JavaScript expressions or commands in strings?
Like I have proposed in my example: interpretStringAsJSExpression(conditional)
Upvotes: 33
Views: 2787
Reputation: 106
Another option aside from eval
is to use the Function constructor. Function
is a bit more flexible and allows you to save compiled code instead of having to eval
it each time.
They both carry similar security risks, however.
var conditional = "";
for(var i = 1; i <= 6; i++){
conditional += "document.getElementById('div" + i +"').innerHTML";
if(i < 6) {
conditional += " && ";
}
}
const f = new Function('return (' + conditional + ') !== ""');
console.log(f());
<div id="div1">1</div>
<div id="div2"></div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5"></div>
<div id="div6">6</div>
Upvotes: 2
Reputation: 29099
You could just store the document.getElementById('divXX').innerHTML
items in an array, and then, just use
items.reduce((a, b) => a && b);
That way, you can change individual div
elements in your expression without having to re-created the whole list
Upvotes: 1
Reputation: 31712
Why interpret a string of code? There are other means like for
loops:
var conditionResult = true;
for(var i = 1; conditionResult && (i < 101); i++) {
conditionResult = conditionResult && document.getElementById('div' + i).innerHTML;
}
if(conditionResult) {
// Do something here
}
The for
loop condition conditionResult && (i < 101)
will break the loop once conditionResult
is determined to be falsy; no need to keep looping in this case.
You can also use array methods like some
and every
if you have the elements in an array:
var arr = [/* array of DOM elements */];
var conditionResult = arr.every(elem => elem.innerHTML); // This is equivalent to (innerHTML && innerHTML && ...)
var conditionResult = arr.some(elem => elem.innerHTML); // This is equivalent to (innerHTML || innerHTML || ...)
Upvotes: 8
Reputation: 2161
As the other answers said, you can solve your conditions problem more easily.
But, to answer your new question
purely from a place of curiosity, is it possible to store and run JavaScript expressions or commands in strings?
Yes, you can write JavaScript code to a string and execute it later with eval. Which you should not do if you are concerned with security or performance.
Upvotes: 20
Reputation: 9782
Use document.querySelectorAll for this type of operation
// Get all the divs that have ids which start with div
var theDivs = document.querySelectorAll('[id^="div"]');
var i,l,el,divsWithContent = [];
// Loop through all theDivs
l = theDivs.length;
for(i = 0; i < l; i++) {
// el is the div
el = theDivs[i];
// Test to make sure the id is div followed by one or more digits
if (/^div\d+$/.test(el.id)) {
// If the div has something in it other than spaces, it's got content
if (el.textContent.trim() !== "") {
// Save the divs with content in the array
divsWithContent.push(el.id);
}
}
}
// Show the results
document.getElementById("result").textContent = divsWithContent.join("\n");
<h1>Div test</h1>
<div id="div1">This</div>
<div id="div2">that</div>
<div id="div3"></div>
<div id="div4">and</div>
<div id="div5">the other thing</div>
<h2>Divs with content</h2>
<pre id="result"></pre>
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
Upvotes: 2
Reputation: 782683
You can do the tests in a loop.
var allOK = true;
for (var i = 1; i <= 100; i++) {
if (!document.getElementById("div"+i).innerHTML) {
allOK = false;
break;
}
}
if (allOK) {
console.log("all my divs have content");
}
You could also give all your DIVs a common class, then use a built-in iterator.
var allDivs = document.getElementsByClassName("divClass");
if (Array.from(allDivs).every(div => div.innerHTML)) {
console.log("all my divs have content");
}
Upvotes: 26
Reputation: 22969
You can set condition
to true
and check each one, setting condition
to false and break out of the loop if any are false.
var conditional = true;
for(var i = 1; i <= 100; i++){
if (!document.getElementById('div' + i).innerHTML) {
condition = false;
break;
}
}
Upvotes: 2