td element not parsed to int

时间:2019-01-07 13:03:12

标签: javascript html

I have a table with id #tab1. For each row, I want to calculate the value of column Points / Matches and to put it in the column Coeficiency, but my code doesn't work. The numbers aren't parsed to int. I would always like to know if elem[4].innerHTML(z); is ok to set coeficiency.

Average();

function Average() {
  var table = document.getElementById('tab1'),
    rows = table.getElementsByTagName('tbody')[1].getElementsByTagName('tr');

  //console.log(rows.length);

  for (var i = 0; i < rows.length; i++) {
    elem = rows[i].getElementsByClassName("columns");
    var x = parseInt(elem[2]);
    var y = parseInt(elem[3]);
    // console.log(x+y," ");
    console.log(x, " ", y);
    var z = y / x;
    elem[4].innerHTML(z);
  }
<div id="mytable">
  <table id="tab1">
    <tr class="rows">
      <th class="columns">#</th>
      <th class="columns">Team</th>
      <th class="columns">Matches</th>
      <th class="columns">Points</th>
      <th class="columns">Coeficiency</th>
    </tr>
    <tbody>
      <tr class="rows">
        <td class="columns">1</td>
        <td class="columns">Baetasii</td>
        <td class="columns">3</td>
        <td class="columns">9</td>
        <td class="columns">100%</td>
      </tr>
      <tr class="rows">
        <td class="columns">2</td>
        <td class="columns">Carcotasii</td>
        <td class="columns">2</td>
        <td class="columns">5</td>
        <td class="columns">100%</td>
      </tr>
    </tbody>
  </table>
</div>

3 个答案:

答案 0 :(得分:1)

好的,所以有几个指针检查了您的代码,首先innerHTML不是一个函数,它是一个简单的属性,您可以重新分配它,但是,我建议使用textContent使用innerHTML可以允许XSS发生。

我的意思是,我知道在特定情况下XSS可能不是问题,但是我认为提及这一点很有价值。

此外,正如我在上面的评论中所提到的,使用parseInt,您需要向其传递一个字符串,而不是最初执行的对象。使用getElementsByClassNamequerySelectorAll之类的函数,您将拥有一个类似数组的对象,例如HTMLCollection,其中包含许多对象,通常是Elements或{{ 3}}。

Average();

function Average() {
  var table = document.getElementById('tab1'),
    rows = table.getElementsByTagName('tbody')[1].getElementsByTagName('tr');

  //console.log(rows.length);

  for (var i = 0; i < rows.length; i++) {
    elem = rows[i].getElementsByClassName("columns");
    var x = parseInt(elem[2].textContent);
    var y = parseInt(elem[3].textContent);
    // console.log(x+y," ");
    console.log(x, " ", y);
    var z = y / x;
    elem[4].textContent = z;
  }
}
<div id="mytable">
  <table id="tab1">
    <tr class="rows">
      <th class="columns">#</th>
      <th class="columns">Team</th>
      <th class="columns">Matches</th>
      <th class="columns">Points</th>
      <th class="columns">Coeficiency</th>
    </tr>
    <tbody>
      <tr class="rows">
        <td class="columns">1</td>
        <td class="columns">Baetasii</td>
        <td class="columns">3</td>
        <td class="columns">9</td>
        <td class="columns">100%</td>
      </tr>
      <tr class="rows">
        <td class="columns">2</td>
        <td class="columns">Carcotasii</td>
        <td class="columns">2</td>
        <td class="columns">5</td>
        <td class="columns">100%</td>
      </tr>
    </tbody>
  </table>
</div>

编辑

我以为我还会包含一个更整洁的版本,它的逻辑作用差不多,它或多或少只是使用了更多“功能样式”的更现代的JavaScript语法。起初,我基本上复制了您为简单起见提供的完全相同的样式,但我认为这样做存在一些问题。例如,您如何为Average使用大写字母,就班级而言,我个人仅在名称开头使用大写字母,这是个人选择,但是请随时不同意或坚持到你所知道的!

我个人更喜欢使用更现代的语法作为个人,我认为它更易于阅读,更简洁明了,通常看起来通读更少的代码。

// States if an array like object is empty or not. 
const isEmpty = a => a.length > 0;

// Returns the text content of a html object.
const txt = td => td == null ? null : td.textContent;

// Simply updates the UI.
const render = tds => v => tds[4].textContent = parseFloat(v).toFixed(2);

// Works out whether or not to fire update or do nothing.
const compute = tds => isEmpty(tds) ? render(tds)(txt(tds[3]) / txt(tds[2])) : null;

// Gets the average for each tr. 
const avg = trs => trs.forEach(tr => compute(tr.querySelectorAll("td")));

// Fire the avg function. 
const update = () => avg(document.querySelectorAll("#tab1 tbody tr"));

// Render tr tag.
const renderTr = i => n => m => p => `<tr>
  <td>${i}</td><td>${n}</td><td>${m}</td><td>${p}</td><td></td>
</tr>`;

// Add a table row.
const append = () => {
  const tbl = document.getElementById("tab1");
  const i = document.querySelectorAll("#tab1 tbody tr").length,
    n = '_____',
    m = Math.floor(Math.random() * 10) + 1,
    p = Math.floor(Math.random() * 10) + 1;

  // Safe-ish because what's being entered is controlled 100%.
  // But generally try not to use innerHTML.
  tbl.innerHTML += renderTr(i)(n)(m)(p);
  update();
};

// Allow for auto add. 
document.getElementById("add").onclick = append;
update(); // Initial run. 
<div id="mytable">
  <table id="tab1">
    <tr class="rows">
      <th class="columns">#</th>
      <th class="columns">Team</th>
      <th class="columns">Matches</th>
      <th class="columns">Points</th>
      <th class="columns">Coeficiency</th>
    </tr>
    <tbody>
      <tr class="rows">
        <td class="columns">1</td>
        <td class="columns">Baetasii</td>
        <td class="columns">3</td>
        <td class="columns">9</td>
        <td class="columns">100%</td>
      </tr>
      <tr class="rows">
        <td class="columns">2</td>
        <td class="columns">Carcotasii</td>
        <td class="columns">2</td>
        <td class="columns">5</td>
        <td class="columns">100%</td>
      </tr>
    </tbody>
  </table>
</div>

<button id="add">Add Row</button>

答案 1 :(得分:0)

getElementsByClassName returns an array-like object of all child elements which have all of the given class names.

Since we have a collection of DOM elements, elem[2] it's a DOM element and you should access its textContent property.

Also, you're using innerHTML property in a wrong way. Just replace

 elem[4].innerHTML(z);

to

 elem[4].innerHTML = z;

Average();

function Average() {
  var table = document.getElementById('tab1'),
    rows = table.getElementsByTagName('tbody')[1].getElementsByTagName('tr');

  for (var i = 0; i < rows.length; i++) {
    elem = rows[i].getElementsByClassName("columns");
    var x = parseInt(elem[2].textContent);
    var y = parseInt(elem[3].textContent);
    console.log(x, " ", y);
    var z = y / x;
    elem[4].innerHTML = z;
  }
}
<div id="mytable">
  <table id="tab1">
    <tr class="rows">
      <th class="columns">#</th>
      <th class="columns">Team</th>
      <th class="columns">Matches</ht>
        <th class="columns">Points</th>
        <th class="columns">Coeficiency</th>
        <tbody>
          <tr class="rows">
            <td class="columns">1</td>
            <td class="columns">Baetasii</td>
            <td class="columns">3</td>
            <td class="columns">9</td>
            <td class="columns">100%</td>
          </tr>
          <tr class="rows">
            <td class="columns">2</td>
            <td class="columns">Carcotasii</td>
            <td class="columns">2</td>
            <td class="columns">5</td>
            <td class="columns">100%</td>
          </tr>
        </tbody>
  </table>
</div>

答案 2 :(得分:0)

使用对象#值数组#forEach #getElementsByTagName

主要问题是您需要使用innerText来检索文本值。

您也不需要多余的类名。

const table = document.getElementById("table");
const rows = table.querySelectorAll("tbody > tr");

Object.values(rows).forEach(row => {
  const tds = row.getElementsByTagName('td');
  if (tds.length === 5) {
    const x = parseInt(tds[2].innerText),
      y = parseInt(tds[3].innerText);
    const z = y / x;
    tds[4].innerText = `${z}`;
  }
});
<table id="table">
  <tr>
    <th>#</th>
    <th>Team</th>
    <th>Matches</th>
    <th>Points</th>
    <th>Coeficiency</th>
  </tr>
  <tbody>
    <tr>
      <td>1</td>
      <td>Baetasii</td>
      <td>3</td>
      <td>9</td>
      <td>100%</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Carcotasii</td>
      <td>2</td>
      <td>5</td>
      <td>100%</td>
    </tr>
  </tbody>
</table>