【问题标题】:how to do table calculations and iterations with javascript?如何使用 javascript 进行表格计算和迭代?
【发布时间】:2020-12-05 10:55:11
【问题描述】:

背景: 我正在尝试学习javascript,所以我决定尝试制作一个类似电子表格的东西来学习循环。现在我已经断断续续地工作了一个多月,我真的可以使用一些额外的帮助。由于我正在尝试学习 vanilla js,因此我试图远离其他任何事情。

到目前为止: 我找到了用于计算行和整个表的不同解决方案,但我觉得这些解决方案中的任何一个都不是很好。主要是我一直在为此使用 for 循环,但我注意到 foreach 可能会更好,我正在努力学习......所以现在我正在尝试理解嵌套的 foreach 循环。

问题: 由于我将使用表格中不同位置的每个单元格的数据,因此我需要弄清楚如何将每一行与其余行分开,然后将特定行中的每个单元格分开(用于计算列) .

解决方案: 正如我所说,我有一些用于计算行甚至整个表的奇怪解决方案,但它们并没有真正回答我的问题。一个想法,我在这里可能是非常错误的,是以某种方式将每一行变成一个数组。
我知道以前在这里问过类似的问题,并且我已经测试了其中的几个,但我仍然卡住了。

我已将所有代码放在下面的 fiddlejs 中。该表已设置为在更改时工作。


非常感谢任何形式的帮助

https://jsfiddle.net/mpv0ds5g/1/

HTML:

<body>
    <div class="container">
      <!-- FORM 1 -->
      <form>
        <table>
          <caption>
            <strong>FIRST</strong>
          </caption>
          <tbody>
            <!-- ROW 0 -->
            <tr>
              <th scope="row">Row 0</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 1 -->
            <tr>
              <th scope="row">Row 1</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 2 -->
      <form>
        <table>
          <caption>
            <strong>SECOND</strong>
          </caption>
          <tbody>
            <!-- ROW 2 -->
            <tr>
              <th scope="row">Row 2</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 3 -->
            <tr>
              <th scope="row">Row 3</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 4 -->
            <tr>
              <th scope="row">Row 3</th>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 3 -->
      <form>
        <table>
          <caption>
            <strong>THIRD</strong>
          </caption>
          <tbody>
            <!-- ROW 4 -->
            <tr>
              <th scope="row">Row 4</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 5 -->
            <tr>
              <th scope="row">Row 5</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 4 -->
      <form>
        <table>
          <caption>
            <strong>FOURTH</strong>
          </caption>
          <tbody>
            <!-- ROW 6 -->
            <tr>
              <th scope="row">Row 6</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 7 -->
            <tr>
              <th scope="row">Row 7</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 8 -->
            <tr>
              <th scope="row">Row 8</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 9 -->
            <tr>
              <th scope="row">Row 9</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 5 -->
      <form>
        <table>
          <caption>
            <strong>FIFTH</strong>
          </caption>
          <tbody>
            <!-- ROW 10 -->
            <tr>
              <th scope="row">Row 10</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 11 -->
            <tr>
              <th scope="row">Row 11</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 12 -->
            <tr>
              <th scope="row">Row 12</th>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="rowsum output output">0</output></td>
            </tr>
            <!-- ROW 13 -->
            <tr>
              <th scope="row">Row 13</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 14 -->
            <tr>
              <th scope="row">Row 14</th>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
    </div>
    <script src="/app.js"></script>
  </body>

JS:

const forms = document.querySelectorAll("form");

forms.forEach(() => {
  f0 = forms[0];
  f1 = forms[1];
  f2 = forms[2];
  f3 = forms[3];
  f4 = forms[4];

  f0.onchange = editSheet;
  f1.onchange = editSheet;
  f2.onchange = editSheet;
  f3.onchange = editSheet;
  f4.onchange = editSheet;
});

function editSheet() {
  const body = document.querySelectorAll("tbody");
  const allrows = document.querySelectorAll("tr");
  const input = document.querySelectorAll("input");


// unwanted for-loop. Gets the job done, but returns html-error in the console
  for (i = 0; i < allrows.length; i++) {
    rowTotal = 0;
    for (ii = 0; ii < allrows[i].getElementsByTagName("input").length; ii++) {
      rowTotal =
        rowTotal + Number(allrows[i].getElementsByTagName("input")[ii].value);
    }
    allrows[i].querySelector(".rowsum").innerHTML = rowTotal;
  }

  /*
  body.forEach(() => {
    console.log(body[0]);
  }); // gives every <tbody>
  */

  /*
  allrows.forEach((i, ix) => {
    console.log(ix, i);
  }); // gives every <tr>
*/
  /*
  input.forEach((i, ix) => {
    console.log(ix, i.value);
  }); // gives every value in the cells
  */
}

【问题讨论】:

    标签: javascript foreach html-table calc


    【解决方案1】:

    一些表格基础知识...

    表格有保留字“rows”和“cells”,让生活更轻松。

    单元格的内容可以通过...访问

    T.rows[x].cells[y].innerHTML
    

    因此,要获得 [row 6 , cell 4] 的值,我们需要...

    var value = T.rows[6].cells[4].innerHTML; // "T" being the ID of the table.
    

    要遍历一个表,我们去......

    for(var x=0; x<T.rows.length; x++){
    
      T.rows[x].cells[3].innerHTML=5; // set the 3rd cell of every row to 5
    }
    

    现在嵌套循环遍历每个单元格...

    for(var x=0; x<T.rows.length; x++){
    
     for(var y=0; y<T.cells.length; y++){
    
      T.rows[x].cells[y].innerHTML=0; // Initialise all cells with zero.
    
     }
    
    }
    

    【讨论】:

    • 非常感谢。我还没有尝试过,但我想这将启用计算列以及在其他地方使用数字,例如,将第 0 行和第 1 行相加并在第 7 行显示总和?
    • 一个非常好的事情是您可以定位每个单元格。这对于较低的桌子非常有用。虽然 cells.length 给出了一个错误:“app.js:42 Uncaught TypeError: Cannot read property 'length' of undefined”。
    【解决方案2】:

    第四个表没有rowsum 类的元素。这会导致错误,因为allrows[i].querySelector(".rowsum") 返回null。反过来,这是因为没有要返回的 rowsum 元素。

    至于循环本身,for 循环可以替换为.forEach 调用。

    【讨论】:

    • 啊啊啊,很棒的信息。我会看看那个。非常感谢:)
    • 摆脱该错误消息的好方法。谢谢。 forEach 循环即将到来,但嵌套循环仍然有点棘手,并且仍在努力添加列:-/
    【解决方案3】:

    我会做一些不同的事情。我不会循环遍历每个表单中的每一行,而是使用 event.target 检测更改了哪个输入,然后通过 DOM “向上遍历”到父 &lt;tr&gt;(通过 parentElement)和 querySelect从那个元素。

    我认为代码是不言自明的。我在 editSheet() 中添加了一些额外的变量,以便更清楚地了解发生了什么。

    我还更改了您的 forEach 循环,因此它有点动态(添加或删除表单而无需更新代码)并且代码更少。

    const forms = document.querySelectorAll("form");
    
    forms.forEach((formElement) => {
      formElement.onchange = editSheet;
    
    /*  f0 = forms[0];
      f1 = forms[1];
      f2 = forms[2];
      f3 = forms[3];
      f4 = forms[4];
    
      f0.onchange = editSheet;
      f1.onchange = editSheet;
      f2.onchange = editSheet;
      f3.onchange = editSheet;
      f4.onchange = editSheet;*/
    });
    
    function editSheet(event) {
      const inputElement     = event.target;  // the input that sent the event
      const tableCellElement = inputElement.parentElement;      // td
      const tableRowElement  = tableCellElement.parentElement;  // tr
      
      const tableCellElements = tableRowElement.querySelectorAll('input');
      const outputElement     = tableRowElement.querySelector('output');
      
      let totalSum = 0;
      const DEFAULT_ZERO = 0;
      
      for (let i = 0; i < tableCellElements.length; i++) {
        totalSum += Number(tableCellElements[i].value) || DEFAULT_ZERO;
      }
    
      outputElement.value = totalSum;
    }
    <div class="container">
      <!-- FORM 1 -->
      <form>
        <table>
          <caption>
            <strong>FIRST</strong>
          </caption>
          <tbody>
            <!-- ROW 0 -->
            <tr>
              <th scope="row">Row 0</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 1 -->
            <tr>
              <th scope="row">Row 1</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 2 -->
      <form>
        <table>
          <caption>
            <strong>SECOND</strong>
          </caption>
          <tbody>
            <!-- ROW 2 -->
            <tr>
              <th scope="row">Row 2</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 3 -->
            <tr>
              <th scope="row">Row 3</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 4 -->
            <tr>
              <th scope="row">Row 3</th>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 3 -->
      <form>
        <table>
          <caption>
            <strong>THIRD</strong>
          </caption>
          <tbody>
            <!-- ROW 4 -->
            <tr>
              <th scope="row">Row 4</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 5 -->
            <tr>
              <th scope="row">Row 5</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 4 -->
      <form>
        <table>
          <caption>
            <strong>FOURTH</strong>
          </caption>
          <tbody>
            <!-- ROW 6 -->
            <tr>
              <th scope="row">Row 6</th>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><input type="number" value="0" /></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 7 -->
            <tr>
              <th scope="row">Row 7</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 8 -->
            <tr>
              <th scope="row">Row 8</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
            <!-- ROW 9 -->
            <tr>
              <th scope="row">Row 9</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output></output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
      <!-- FORM 5 -->
      <form>
        <table>
          <caption>
            <strong>FIFTH</strong>
          </caption>
          <tbody>
            <!-- ROW 10 -->
            <tr>
              <th scope="row">Row 10</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 11 -->
            <tr>
              <th scope="row">Row 11</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 12 -->
            <tr>
              <th scope="row">Row 12</th>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="editTable output output">0</output></td>
              <td><output class="rowsum output output">0</output></td>
            </tr>
            <!-- ROW 13 -->
            <tr>
              <th scope="row">Row 13</th>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="editTable output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
            <!-- ROW 14 -->
            <tr>
              <th scope="row">Row 14</th>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="colsum output">0</output></td>
              <td><output class="rowsum output">0</output></td>
            </tr>
          </tbody>
        </table>
      </form>
      <hr />
    </div>

    【讨论】:

    • 太好了。我真的认为应该有一种更有效的方法来做到这一点。关于 event.target 的好主意。我绝对会调查的。非常感谢。
    • 这是计算行数的绝佳解决方案。我在列方面遇到了困难:(而且我不太确定(还没有到那部分),如何将输入进一步向下移动。例如,如果我想添加第一个第一行的单元格与第二行的第一个单元格并在第 9 行的第一个单元格中输出。
    • 好的,这就是为什么你在后面的行中有这么多输出。我想你需要为此构建一个复杂的数据结构,这很简单,但工作量很大。如果你只是在学习 javascript,那并不是你真正应该做的项目,尤其是当有像 React、Angular、Polymer 和 Vue 这样的框架可以毫无困难地做到这一点时,因为该功能是框架中的一个小功能。
    • 啊啊,我明白了。是的,这对我来说是一个很大的挑战,哈哈。非常感谢您的回答,这实际上比您想象的更有帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 2017-03-23
    相关资源
    最近更新 更多