Программно построить условие для использования в операторе if()

Предположим на минуту, что у меня есть что-то вроде этого:

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)

Очевидно, что напечатать и поддерживать такое большое условное утверждение проблематично.

Я хотел бы какое-то решение, как:

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");
}

Возможно ли что-то подобное в JavaScript?

Великие ответы были представлены, и я уверен, что я и другие выиграем от них. Тем не менее, чисто из любопытства, возможно ли хранить и запускать выражения или команды JavaScript в строках?

Как я предложил в моем примере: interpretStringAsJSExpression(conditional)

Ответы

Ответ 1

Как и в других ответах, вы можете решить вашу проблему с условиями проще.

Но, чтобы ответить на ваш новый вопрос

Можно ли хранить и запускать выражения или команды JavaScript в виде строк из любопытства?

Да, вы можете написать код JavaScript в строку и выполнить его позже с помощью eval. Что вы не должны делать, если вы обеспокоены безопасностью или производительностью.

Ответ 2

Вы можете делать тесты в цикле.

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");
}

Вы также можете дать всем вашим DIV общий класс, а затем использовать встроенный итератор.

var allDivs = document.getElementsByClassName("divClass");
if (Array.from(allDivs).every(div => div.innerHTML)) {
    console.log("all my divs have content");
}

Ответ 3

Зачем интерпретировать строку кода? Есть и другие средства, как for петель:

var conditionResult = true;
for(var i = 1; conditionResult && (i < 101); i++) {
    conditionResult = conditionResult && document.getElementById('div' + i).innerHTML;
}

if(conditionResult) {
    // Do something here
}

Условие цикла for conditionResult && (i < 101) прервет цикл, как только conditionResult определено как ложное; нет необходимости продолжать цикл в этом случае.

Вы также можете использовать методы массива, как some и every если у вас есть элементы в массиве:

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 || ...)

Ответ 4

Вы можете установить condition в true и проверить каждое из них, установив condition в false и выйти из цикла, если таковые имеются в false.

var conditional = true;
for(var i = 1; i <= 100; i++){
  if (!document.getElementById('div' + i).innerHTML) {
        condition = false;
        break;
    }
}

Ответ 5

Используйте document.querySelectorAll для этого типа операции

// 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 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>

Ответ 6

Вы можете просто сохранить document.getElementById('divXX').innerHTML элементы в массиве, а затем просто использовать

items.reduce((a, b) => a && b);

Таким образом, вы можете изменить отдельные элементы div в своем выражении, не создавая заново весь список

Ответ 7

Другой вариант, кроме eval заключается в использовании конструктора Function. Function немного более гибкая и позволяет вам сохранять скомпилированный код вместо того, чтобы каждый раз eval его. Однако они оба несут схожие риски безопасности.

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>