简体   繁体   English

Javascript 嵌套循环使浏览器崩溃

[英]Javascript nested loop crashes browser

I am creating a web app with Django and I require some Javascript for changing styles of dynamically generated elements.我正在使用 Django 创建一个网络应用程序,我需要一些 Javascript 来更改动态生成元素的样式。 I have simplified the code to just static html and javascript.我已将代码简化为静态 html 和 javascript。

Goal: The code causing problems is acting on detail pages.目标:导致问题的代码作用于详细信息页面。 There are many detail pages, each representing data from a given database entry.有许多详细信息页面,每个页面都代表来自给定数据库条目的数据。 Each page will have 1 or more table, depending on how many protein names the database entry has.每个页面将有 1 个或多个表格,具体取决于数据库条目有多少蛋白质名称。 For each table, I want to change the colour of the entry for the protein name in the table heading as well as the entry for the example_id.对于每个表,我想更改表标题中蛋白质名称条目的颜色以及 example_id 条目的颜色。

Attempt: I am using javascript to capture the example_id from the top level heading and the protein names from the table headings.尝试:我正在使用 javascript 来捕获顶级标题中的 example_id 和表标题中的蛋白质名称。 I am then capturing the nodelist of table rows and iterating through, looking for entries that match either the protein name or the example_id.然后我捕获表行的节点列表并遍历,寻找与蛋白质名称或 example_id 匹配的条目。

Problem: When iterating over the nodelist of protein names taken from the table headers in a nested loop the page never loads.问题:当迭代从嵌套循环中的表头获取的蛋白质名称的节点列表时,页面永远不会加载。

HTML: HTML:

<html>
  <body>
    <h1 class="msaIdCatcher">Protein Record #example_id</h1>
    
      <h2>Multiple Sequence Alignment</h2>

        


        <h3 class= "msaProtNameCatcher">Protein_name1</h3>
          <p>The following is a multiple sequence alignment (MSA) of all sequences predicted to be Protein_name1 sequences.</p>

          <table>

            <tr class=sequenceidrow>
              <th class=sequenceid>not_example_id1</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
            <tr class=sequenceidrow>
              <th class=sequenceid>Protein_name1</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
            <tr class=sequenceidrow>
              <th class=sequenceid>not_example_id3</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
            <tr class=sequenceidrow>
              <th class=sequenceid>example_id</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
            <tr class=sequenceidrow>
              <th class=sequenceid>not_example_id4</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
          </table>
        <h3 class="msaProtNameCatcher">Protein_name2</h3>
          <p>The following is a multiple sequence alignment (MSA) of all sequences predicted to be Protein_name2 sequences.</p>

          <table>
            <tr class=sequenceidrow>
              <th class=sequenceid>not_example_id1</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
            </tr>
            <tr class=sequenceidrow>
              <th class=sequenceid>not_example_id2</th>
              <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
              </tr>
              <tr class=sequenceidrow>
                  <th class=sequenceid>not_example_id3</th>
                  <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
              </tr>
              <tr class=sequenceidrow>
                  <th class=sequenceid>example_id</th>
                  <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
              </tr>
              <tr class=sequenceidrow>
                  <th class=sequenceid>not_example_id4</th>
                  <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
              </tr>
              <tr class=sequenceidrow>
                  <th class=sequenceid>Protein_name2</th>
                  <td class="alignsequence">aaaaaaaaaaaaaaaaaaaa</td>
              </tr>
            </table>
  </body>
</html>




var idTitle = document.getElementsByClassName("msaIdCatcher");
id = idTitle[0].innerHTML;
id = id.replace("Protein Record #", "");

//Get protein_names from table headers
proteinnameElements = document.getElementsByClassName("msaProtNameCatcher")

//Get table rows
var sequenceidrowElements = document.getElementsByClassName("sequenceidrow");

//Loop through table rows
for (var i = 0; i < sequenceidrowElements.length; i++) {

    //Get sequence id
    var sequenceidElement = sequenceidrowElements[i].getElementsByClassName("sequenceid");
    idElement = sequenceidElement[0].innerHTML

    //Check if ID is ID from page heading
    if (idElement == id) {

        //Get sequence element and change colour of ID and sequence elemnt
        var alignsequenceElement = sequenceidrowElements[i].getElementsByClassName("alignsequence");
        sequenceidElement[0].style.color = "#b80090";
        alignsequenceElement[0].style.color = "#b80090";
    }

    //Loop through protein names in table headers and Check if ID in table matches protein name
    //Then change colour of ID and sequence
    for (var i = 0; i < proteinnameElements.length; i++) {
        proteinname = proteinnameElements[i].innerHTML
        if (idElement == proteinname) {
            var alignsequenceElement = sequenceidrowElements[i].getElementsByClassName("alignsequence");
            sequenceidElement[0].style.color = "red";
            alignsequenceElement[0].style.color = "red";
        }
    }
}

However, when using a single protein name by making proteinname equal to the innerHTML of the first element proteinnameElements and taking away the loop nesting as follows, the page loads in a fraction of a second. 

var idTitle = document.getElementsByClassName("msaIdCatcher");
id = idTitle[0].innerHTML;
id = id.replace("Protein Record #", "");

//Get protein_names from table headers
proteinnameElements = document.getElementsByClassName("msaProtNameCatcher")
proteinname = proteinnameElements[0].innerHTML
//Get table rows
var sequenceidrowElements = document.getElementsByClassName("sequenceidrow");

//Loop through table rows
for (var i = 0; i < sequenceidrowElements.length; i++) {

    //Get sequence id
    var sequenceidElement = sequenceidrowElements[i].getElementsByClassName("sequenceid");
    idElement = sequenceidElement[0].innerHTML

    //Check if ID is ID from page heading
    if (idElement == id) {

        //Get sequence element and change colour of ID and sequence elemnt
        var alignsequenceElement = sequenceidrowElements[i].getElementsByClassName("alignsequence");
        sequenceidElement[0].style.color = "#b80090";
        alignsequenceElement[0].style.color = "#b80090";
    }

    //Loop through protein names in table headers and Check if ID in table matches protein name
    //Then change colour of ID and sequence
        if (idElement == proteinname) {
            var alignsequenceElement = sequenceidrowElements[i].getElementsByClassName("alignsequence");
            sequenceidElement[0].style.color = "red";
            alignsequenceElement[0].style.color = "red";
        }
}

Can someone help me understand why nesting loops in this way causes such a large difference in runtime and help me find a way to solve my problem?

Thanks!

Your inner loop begins with var i , because of how scoping works in JavaScript, it will be the same i as the outer loop, and it will be changed everytime the inner loop is run (thereby never increasing the outer loop, making it endless);你内环开始var i ,因为如何在JavaScript作用域的作品,这将是相同的i为外循环,这将是改变每次内循环运行(从而从来没有增加外循环,使得它无穷的) ; it's like typing this:就像输入这个:

var i;
for (i = 0; i < length; ++i)
{
    for (i = 0; i < length2; ++i)
    {
        //...
    }
}

Either use a different variable name for the inner loop ( j is a common choice), or use the let keyword (which will ensure the variables are locally scoped), this is the let keyword (note that it's relatively recent):要么为内循环使用不同的变量名( j是一个常见的选择),要么使用let关键字(这将确保变量是局部范围的),这是 let 关键字(注意它是相对较新的):

for (let i = 0; i < length; ++i)
{
    //...
}

Hope this helps clear things up.希望这有助于澄清事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM