admin管理员组

文章数量:1288005

I'm looking for a way to change some table headers. And some of these headers contain addition HTML code, like line breaks.

This is the typical setup of the table on the page (page source):

<table class="awesometable" style="width: 100%; margin-right: 0;">
    <tr>
        <th style="background: red; color: white;">Male<br /> contestant</th>
        <th style="background: red; color: white;">Female<br /> contestant</th>
    </tr>
</table>

Where Male<br /> contestant, Female<br /> contestant (and a series of other slight variation) should be changed to a simple symbol like and .

Using document.body.innerHTML.replace() replaces the entire DOM with new nodes, which is undesired, and can also change other instances were the text in the table header is also in plain text and were it shouldn't be changed, although this is rare, and only a minor issue.

Using a selective nodeType == 3 fails on the additional line breaks.

Any ideas are wele, code examples (here or at, for example, jsfiddle) are always preferred. Thanks.

I'm looking for a way to change some table headers. And some of these headers contain addition HTML code, like line breaks.

This is the typical setup of the table on the page (page source):

<table class="awesometable" style="width: 100%; margin-right: 0;">
    <tr>
        <th style="background: red; color: white;">Male<br /> contestant</th>
        <th style="background: red; color: white;">Female<br /> contestant</th>
    </tr>
</table>

Where Male<br /> contestant, Female<br /> contestant (and a series of other slight variation) should be changed to a simple symbol like and .

Using document.body.innerHTML.replace() replaces the entire DOM with new nodes, which is undesired, and can also change other instances were the text in the table header is also in plain text and were it shouldn't be changed, although this is rare, and only a minor issue.

Using a selective nodeType == 3 fails on the additional line breaks.

Any ideas are wele, code examples (here or at, for example, jsfiddle) are always preferred. Thanks.

Share Improve this question edited Jun 12, 2011 at 18:47 Eric 97.7k54 gold badges255 silver badges389 bronze badges asked Jun 12, 2011 at 18:36 OroborosOroboros 331 gold badge1 silver badge3 bronze badges 5
  • 2 Use innerHTML on the table head elements only... – Felix Kling Commented Jun 12, 2011 at 18:39
  • 1 @Felix innerHTML has problems with tables in (yup, you guessed it) IE. quirksmode/dom/w3c_html.html#t03 – Matt Ball Commented Jun 12, 2011 at 18:53
  • @Matt: As far as I understand this, this is only an issue when you want to add or remove rows from the table. Should be fine to replace text of cells (have not tested it though). – Felix Kling Commented Jun 12, 2011 at 18:57
  • 1 @Felix I haven't tested it either but I'd sooner just use innerText. – Matt Ball Commented Jun 12, 2011 at 18:59
  • Matt - innerHTML is fine to use on cell contents, it always has been and always will be. innerText is a proprietary IE property that is not supported by all browsers and is very different to innerHTML. MS documentation has always said don't use innerHTML to modify the table itself. But now that it's part of HTML5 you'll be able to use it for that too in the future. – RobG Commented Jun 12, 2011 at 22:46
Add a ment  | 

3 Answers 3

Reset to default 5

Try this:

  var headers = document.getElementsByTagName('th'); 
  headers[0].innerHTML = '&#x2642;';
  headers[1].innerHTML = '&#x2640;';

Shows the concept. Better to give the respective cells an id or class to identify them rather than using the content. You could also do something like:

  var cell, headers = document.getElementsByTagName('th'); 

  for (var i=0, iLen=headers.length; i<iLen; i++) {
    cell = headers[i];

    if (cell.innerHTML.match('Male') ) {
      cell.innerHTML = '&#x2642;';
    }
      else if (cell.innerHTML.match('Female')) {
      cell.innerHTML = '&#x2640;';
    }    
  }

I'd remend using jQuery just because it's so much friendlier when dealing with the DOM. Note also that it's probably slightly faster -- which may matter if you have a large table -- not to assign something to innerHTML until you've done all the operations on the string. That is, store the value of innerHTML in a variable, run replace functions, then place the result back in innerHTML. (Note also that I'm replacing your <br /> with <br>. At least in Chrome, innerHTML will convert XHTML closed single tags to valid HTML, which here is <br>.)

Here's a more extensible method (jsFiddle Example):

var replacements = [
  ["Male<br>contestant", "♂"],
  ["Female<br>contestant", "♀"]
];

function runReplacement() {
  $(".awesometable th").each(function() {
    var $this = $(this);
    var ih = $this.html();
    $.each(replacements, function(i, arr) {
      ih = ih.replace(arr[0], arr[1]);
    });
    $this.html(ih);
  });
}

In addition to the above, you can use .text() instead of .html() by just ignoring the <br> part of each cell (e.g. replacing "Malecontestant" instead of "Male<br>contestant"). Example here.

EDIT:

And for correcting an example below:

var headers = document.getElementsByTagName("th"); 
for (var i = 0; i < headers.length; i++) {
  headers[i].innerHTML = headers[i].innerHTML.replace("Male<br>contestant", "♂")
                           .replace("Female<br>contestant", "♀");
}

For silliness like focusing on terseness (70 characters shorter, ignoring excess whitespace):

$("th").each(function(){$(this).html($(this).html()
.replace("Male<br>contestant","♂").replace("Female<br>contestant","♀"));});

What's the problem with something like

function replace(text)
{
    return text.replace('Male', '♂').replace('Female', '♀');
}

var ths = document.getElementById('myTable').getElementsByTagName('th'),
    i = ths.length,
    th, text;
while (i-- && (th = ths[i], text = th.innerText))
{
    if (text)
    {
        // IE, Safari, Chrome, Opera
        th.innerText = replace(text);
    }
    else
    {
        // Everything but IE <9
        th.textContent = replace(th.textContent);
    }
}

As requested, jsFiddle: http://jsfiddle/mattball/4EwGt/

Yes, innerText || textContent is a PITA.


I want to replace the entire header, Male<br /> contestant and Female<br /> contestant, not just the first word, and trying the whole in your example doesn't work. Only seems to remove the line break, doesn't change the text.

Use this replace function instead:

function replace(text)
{
    return text.replace('Male\ncontestant', '♂')
        .replace('Female\ncontestant', '♀');
}

Demo: http://jsfiddle/mattball/8W3cM/

本文标签: javascriptChange table headersStack Overflow