使用jQuery迭代HTML表行并更改列值

时间:2018-01-17 12:13:38

标签: javascript jquery html html-table

我有一张看起来像这样的表:

enter image description here

我需要迭代表行,但只想在“价格”列上工作。如果价格高于20,我需要将价格货币更改为美元(例如30美元),如果价格低于20,则将文本颜色更改为红色。

我的表没有id,我不确定如何只在价格列上进行迭代,并更改它们的颜色和货币。 如果我得到一些帮助,我会很高兴的。

以下是我的代码:

 $(document).ready(function () {
        $("table").find('tr').each(function(i,el){
            var tds = $(this).find('td');
            if (tds.eq(5).text() > "20") {
                tds.eq(5).text() = tds.eq(5).text() + "$";       
            }
            else {
                // here i am not sure how to change the color of the text..
            }

        });
    });

4 个答案:

答案 0 :(得分:1)

您可以使用.css()函数设置样式:

if (tds.eq(5).text() > "20") {
     tds.eq(5).text() = tds.eq(5).text() + "$";       
}else{
    tds.eq(5).css('color', 'red');
}

或者您可以直接使用选择器:

$('td:eq(5)', this).css('color', 'red');

答案 1 :(得分:1)

您可以使用each()选择器

省略循环表行的第一个:nth-child()



$('table td:nth-child(2)').each(function() {
  let $this = $(this);

  // make sure it's a number
  if (!isNaN($this.text())) {

    // convert to number and check value
    if (+$this.text() > 20) {
      $this.text($this.text() + '$');
    } else {
      $this.css('color', 'red');
    }
  }

});

th {
  background: lightBlue;
}

th, td {
  border: 1px solid black;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <th>Column</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>Column</td>
    <td>19</td>
  </tr>
  <tr>
    <td>Column</td>
    <td>21</td>
  </tr>
</table>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

理想情况下,您可以向该列添加一个类(我不知道这是否是硬编码的东西,或者您是在迭代列表,但是会假设后者)然后问题就解决了。

$(document).ready(function() {
   $("table .price").each(function(i, el) {
      if($(this).text() > "20")
         $(this).text() = $(this).text() + '$';
      else
         $(this).css('color', 'red);
   })
});

答案 3 :(得分:0)

虽然您已经接受了答案,但我想花点时间向您展示一些替代方案;但是,首先,我想在你写这个问题时回答你的问题,并在你的问题中写道:

  

如果价格高于20,我需要将价格货币更改为美元[美元](例如30美元),如果价格低于[20],则将文本颜色更改为红色。

如果价格等于20美元,你不会澄清会发生什么,所以我选择相信如果价格小于20,颜色应该是红色,如果它是&#39 ; s等于或大于20,则应设置货币。虽然,我也选择在价格之前设置货币符号,但要提供$30而不是 - 正如您在问题中所写的那样 - 30$,符合观察到的习惯。美国。

所以,明确回答你的问题:

// finding the <td> elements that are the 6th (one-based CSS
// indexing) child of their <tr> parent, that <tr> contained
// within a <tbody> elementl
$('tbody tr td:nth-child(6)')

  // using the css() method to update the style(s) of those
  // elements:
  .css({

    // updating the 'color' property of the current element
    // using the anonymous function:
    'color': function(index, currentValue) {

      // here 'this' is the current <td> of the collection of
      // <td> elements; we find the current <td> element's
      // textContent, trim it of leading or trailing white-
      // space, using String.prototype.trim(), and parse that
      // textContent using parseFloat() (since prices are
      // not necessarily integers).
      // If the parsed number is less than 20 the 'red' string
      // is returned as the property-value for the 'color'
      // property, otherwise we return the currentValue held for
      // the color property:
      return parseFloat(this.textContent.trim()) < 20 ? 'red' : currentValue;

      // note that we can, instead, return an empty string
      // which would cause the 'color' property not to be
      // set (as a non-valid value causes the rule to be
      // discarded); this could be better for your use case
      // and will allow the usual CSS cascade to apply.

  }

// we then chain with the text() method:
}).text(function(index, currentValue) {

  // here we again parse the trimmed textContent of the
  // current <td> (here the currentValue is the current
  // textContent, so does not have to be retrieved via
  // this.textContent) to a value and test if that value
  // is less than 20. If the value *is* less than 20, we
  // return that value unchanged; if it is *not* less than
  // 20 we prefix the currentValue with a '$' symbol, and
  // return the concatenated string:
  return parseFloat(currentValue.trim()) < 20 ? currentValue : '$' + currentValue;
});

&#13;
&#13;
$('tbody tr td:nth-child(6)').css({
  'color': function(index, currentValue) {
    return parseFloat(this.textContent.trim()) < 20 ? 'red' : currentValue;
  }
}).text(function(index, currentValue) {
  return parseFloat(currentValue.trim()) < 20 ? currentValue : '$' + currentValue;
});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

当然,以上所有内容都可以通过简单的JavaScript轻松实现,如下所示:

// here we use Function.prototype.call() to apply the
// Array.prototype.slice() method to the array-like
// NodeList returned by document.querySelectorAll():
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')

// using Array.prototype.forEach() to iterate over the
// Array of <td> nodes:
).forEach(function(cell, index) {

  // we use String.prototype.trim() to remove leading
  // and/or trailing white-space from current <td> element's
  // textContent, and parse that into a number using
  // parseFloat:
  let currentValue = parseFloat(cell.textContent.trim());

  // if that number is less than 20:
  if (currentValue < 20) {

    // we set the 'color' of the <td> element to 'red':
    cell.style.color = 'red';
  } else {

    // otherwise we return the existing textContent
    // with a preceding '$':
    cell.textContent = '$' + cell.textContent

    // because parseFloat() - and parseInt() - parse
    // the numbers from the beginning of a string until
    // the first non-numeric character we can't rely on
    // currentValue being equal to the complete textContent
    // of the <td>, which is why we return
    //   '$' + cell.textContent
    // instead of
    //   '$' + currentValue

  }
});

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell, index) {
  let currentValue = parseFloat(cell.textContent.trim());
  if (currentValue < 20) {
    cell.style.color = 'red';
  } else {
    cell.textContent = '$' + cell.textContent;
  }
});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}
&#13;
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

显然,如果您的用户可以访问符合ES6标准的浏览器,则可以使用Array.from()和箭头功能重写上述内容(因为我们无法访问,使用或要求this功能):

// converting the Array-like NodeList returned by
// document.querySelectorAll() into an Array:
Array.from(
  document.querySelectorAll('tbody tr td:nth-child(6)')

// using Arrow function syntax to write the anonymous function
// Array.prototype.forEach():
).forEach(

  // 'cell' refers to the current <td> of the array of <td>
  // elements over which we're iterating:
  cell => {

    // here, again, we parse the trimmed textContent of the
    // current <td> to a number:
    let currentValue = parseInt(cell.textContent.trim());

    // if the currentValue is less than 20:
    if (currentValue < 20) {

      // the cell's color is set to 'red':
      cell.style.color = 'red';
    } else {

      // otherwise we preface the cell's textContent
      // with a '$' symbol:
      cell.textContent = '$' + cell.textContent;
    }
  }
);

&#13;
&#13;
Array.from(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(
  cell => {
    let currentValue = parseInt(cell.textContent.trim());
    if (currentValue < 20) {
      cell.style.color = 'red';
    } else {
      cell.textContent = '$' + cell.textContent;
    }
  }
);
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}
&#13;
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

写完后,我希望,充分解释上面解决问题的方法,如下所示是我的建议,你应该使用类格式化单元格内容,而不是直接更新color或文本。

这种方法需要在CSS中添加适当的类,例如我添加了:

.lessThan {
  color: red;
}
.currency::before {
  content: '$';
}

用jQuery来表示:

// selecting the relevant elements (as above), and chaining
// with the addClass() method:
$('tbody tr td:nth-child(6)').addClass(function() {

  // here we trim the textContent of leading/trailing white-space
  // parse that String into a number and, if that number is
  // less-than 20 we return the 'lessThan' string as the class-name
  // to add, otherwise we return the 'currency' class-name:
  return parseFloat(this.textContent.trim()) < 20 ? 'lessThan' : 'currency';
});

&#13;
&#13;
$('tbody tr td:nth-child(6)').addClass(function() {
  return parseInt(this.textContent.trim(), 10) <= 20 ? 'lessThan' : 'currency';
});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}

.lessThan {
  color: red;
}

.currency::before {
  content: '$';
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

上面用JavaScript重写,变成:

// converting the array-like NodeList from
// document.querySelectorAll() into an Array:
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')

// using Array.prototype.forEach() to iterate over
// that Array:
).forEach(function(cell) {

  // 'cell' refers to the current <td> of the Array
  // of <td> elements over which we're iterating;
  // here we use the Element.classList API to add
  // a class-name to the current element:
  cell.classList.add(

    // a ternary operator to assign the 'lessThan' class if
    // the parsed number is less than 20, or the 'currency'
    // class if it is not:
    parseFloat(cell.textContent.trim()) < 20 ? 'lessThan' : 'currency'
  );

});

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell) {
  cell.classList.add(
    parseFloat(cell.textContent.trim()) < 20 ? 'lessThan' : 'currency'
  );

});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}

.lessThan {
  color: red;
}

.currency::before {
  content: '$';
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

使用类来修改元素表示的好处是,它可以更容易地取消修改这些元素,而不必取消设置color属性值或取消修改节点的文本内容;显然,如果将来需求发生变化,它还可以更容易地调整多个不同的属性。

还值得注意的是,在上面的所有代码片段中都有一个简单的if / else,并且无法防范我们正在迭代的单元格具有非数字值,例如:

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell, index) {
  let currentValue = parseFloat(cell.textContent.trim());
  if (currentValue < 20) {
    cell.style.color = 'red';
  } else {
    cell.textContent = '$' + cell.textContent;
  }
});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}
&#13;
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>Two hundred</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

当然,这可以通过使用额外的else if支票来添加,例如:

  cell => {

    // here, again, we parse the trimmed textContent of the
    // current <td> to a number:
    let currentValue = parseInt(cell.textContent.trim()),

        // here we use the isNan() function to check
        // whether the supplied value is not-a-number
        // (which is true if the value is not a valid
        // number), and then we negate that result so
        // assigned variable-name makes sense (and to
        // avoid negation in the assessments of the
        // if/else if):
        isNumber = !isNaN( currentValue );

    // if the currentValue is less than 20:
    if (isNumber && currentValue < 20) {

      // the cell's color is set to 'red':
      cell.style.color = 'red';
    } else if (isNumber) {

      // otherwise we preface the cell's textContent
      // with a '$' symbol:
      cell.textContent = '$' + cell.textContent;
    } else {
      // this 'else' is not required, unless you
      // wish to modify the element in some way
      // when neither of the above assessments
      // are satisfied
    }
  }

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell, index) {
  let currentValue = parseFloat(cell.textContent.trim()),
    isNumber = !isNaN(currentValue);
  if (isNumber && currentValue < 20) {
    cell.style.color = 'red';
  } else if (isNumber) {
    cell.textContent = '$' + cell.textContent;
  }
});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}
&#13;
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>Two hundred</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

在使用三元组的情况下,重写 - 如果简单是一个目标 - 将与上面一样,除非变量将被指定为包含相关或不值:

Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell) {
  let value = parseFloat(cell.textContent.trim()),
    isNumber = !isNaN(value),

    // initialising the name of the class to be added
    // as an undefined variable:
    classToAdd;

  if (isNumber && value < 20) {
    classToAdd = 'lessThan';
  } else if (isNumber) {
    classToAdd = 'currency';
  }

  // as an empty string is not a valid argument for
  // Element.classList.add(), we test that the
  // classToAdd variable is truthy (ie not undefined,
  // false, null, zero-length string, 0...):
  if (classToAdd) {

    // and if it is, we then add the class:
    cell.classList.add(classToAdd);
  }

});

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell) {
  let value = parseFloat(cell.textContent.trim()),
    isNumber = !isNaN(value),
    classToAdd;

  if (isNumber && value < 20) {
    classToAdd = 'lessThan';
  } else if (isNumber) {
    classToAdd = 'currency';
  }

  if (classToAdd){
    cell.classList.add(classToAdd);
  }

});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}

.lessThan {
  color: red;
}

.currency::before {
  content: '$';
}
&#13;
<table>
  <thead>
    <tr>
      <th>PersonID</th>
      <th>LastName</th>
      <th>FirstName</th>
      <th>FromDate</th>
      <th>ToDate</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Davolio</td>
      <td>Nancy</td>
      <td>10-11-2011</td>
      <td>30-12-2010</td>
      <td>Two hundred</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Fuller</td>
      <td>Andrew</td>
      <td>12-01-2011</td>
      <td>30-12-2015</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Leverling</td>
      <td>Janet</td>
      <td>09-03-2011</td>
      <td>30-12-2013</td>
      <td>15</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;

上面我说&#34; 如果简单是一个目标 - 就像上面一样,除了一个变量将被分配...... &#34;虽然有可能 - 但是完全不可取 - 使用多部分三元运算符 1 来避免使用简单,易于阅读且易于维护的if / {{ 1}}:

else if

&#13;
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell) {
  cell.classList.add(

    // beyond the overly complex composition there is the additional
    // problem that an empty-string is not a valid argument to
    // Element.classList.add(), therefore a specified value must
    // be provided; here we use undefined, but that will be coerced
    // to a string ('undefined'), which will show up in the DOM as
    // a class-name:
    parseFloat(cell.textContent.trim()) < 20 ? 'lessThan' : !isNaN(parseFloat(cell.textContent.trim())) ? 'currency' : undefined
  );

});
&#13;
Array.prototype.slice.call(
  document.querySelectorAll('tbody tr td:nth-child(6)')
).forEach(function(cell) {
  cell.classList.add(
    parseFloat(cell.textContent.trim()) < 20 ? 'lessThan' : !isNaN(parseFloat(cell.textContent.trim())) ? 'currency' : undefined
  );

});
&#13;
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

table {
  width: 100vw;
}

.lessThan {
  color: red;
}

.currency::before {
  content: '$';
}
&#13;
&#13;
&#13;

参考文献:

  1. 如果以下所有问题的答案都是&#39; no&#39;

    ,则只考虑这种方法。
    • 你的同事知道你住在哪里吗?
    • 你喜欢甚至喜欢你的同事吗?
    • 你喜欢在家里度过晚上和周末,而不必担心同事找到你吗?
    • 你喜欢,甚至喜欢自己吗?
    • 您喜欢或喜欢在工作日保持易于阅读的代码吗?