最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pull th content into a td data-label attribute - Stack Overflow

programmeradmin4浏览0评论

I'm using a responsive table style that will collapse for smaller screen sizes and display the table header before each cell.

body {
  font-family: "Open Sans", sans-serif;
  line-height: 1.25;
}
table {
  border: 1px solid #ccc;
  border-collapse: collapse;
  margin: 0;
  padding: 0;
  width: 100%;
  table-layout: fixed;
}
table caption {
  font-size: 1.5em;
  margin: .5em 0 .75em;
}
table tr {
  background: #f8f8f8;
  border: 1px solid #ddd;
  padding: .35em;
}
table th,
table td {
  padding: .625em;
  text-align: center;
}
table th {
  font-size: .85em;
  letter-spacing: .1em;
  text-transform: uppercase;
}
@media screen and (max-width: 600px) {
  table {
    border: 0;
  }
  table caption {
    font-size: 1.3em;
  }
  table thead {
    border: none;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    color: red;
    background-color:#000;
  }
  table tr {
    border-bottom: 3px solid #ddd;
    display: block;
    margin-bottom: .625em;
  }
  table td {
    border-bottom: 1px solid #ddd;
    display: block;
    font-size: .8em;
    text-align: right;
  }
  table td:before {
    /*
    * aria-label has no advantage, it won't be read inside a table
    content: attr(aria-label);
    */
    content: attr(data-label);
    float: left;
    font-weight: bold;
    text-transform: uppercase;
  }
  table td:last-child {
    border-bottom: 0;
  }
  table td:first-child{
    color:white;
    background: #000;
  }
}
<table>
  <caption>Statement Summary</caption>
  <thead>
    <tr>
      <th scope="col">Account</th>
      <th scope="col">Estimated arrival date</th>
      <th scope="col">Amount</th>
      <th scope="col">Period</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td data-label="Account">Visa - 3412</td>
      <td data-label="Really freaking long div magic">04/01/2016</td>
      <td data-label="Amount">$1,190</td>
      <td data-label="Period">03/01/2016 - 03/31/2016</td>
    </tr>
    <tr>
      <td scope="row" data-label="Account">Visa - 6076</td>
      <td data-label="Due Date">03/01/2016</td>
      <td data-label="Amount">$2,443</td>
      <td data-label="Period">02/01/2016 - 02/29/2016</td>
    </tr>
    <tr>
      <td scope="row" data-label="Account">Corporate AMEX</td>
      <td data-label="Due Date">03/01/2016</td>
      <td data-label="Amount">$1,181</td>
      <td data-label="Period">02/01/2016 - 02/29/2016</td>
    </tr>
</tbody>
</table>

I'm using a responsive table style that will collapse for smaller screen sizes and display the table header before each cell.

body {
  font-family: "Open Sans", sans-serif;
  line-height: 1.25;
}
table {
  border: 1px solid #ccc;
  border-collapse: collapse;
  margin: 0;
  padding: 0;
  width: 100%;
  table-layout: fixed;
}
table caption {
  font-size: 1.5em;
  margin: .5em 0 .75em;
}
table tr {
  background: #f8f8f8;
  border: 1px solid #ddd;
  padding: .35em;
}
table th,
table td {
  padding: .625em;
  text-align: center;
}
table th {
  font-size: .85em;
  letter-spacing: .1em;
  text-transform: uppercase;
}
@media screen and (max-width: 600px) {
  table {
    border: 0;
  }
  table caption {
    font-size: 1.3em;
  }
  table thead {
    border: none;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    color: red;
    background-color:#000;
  }
  table tr {
    border-bottom: 3px solid #ddd;
    display: block;
    margin-bottom: .625em;
  }
  table td {
    border-bottom: 1px solid #ddd;
    display: block;
    font-size: .8em;
    text-align: right;
  }
  table td:before {
    /*
    * aria-label has no advantage, it won't be read inside a table
    content: attr(aria-label);
    */
    content: attr(data-label);
    float: left;
    font-weight: bold;
    text-transform: uppercase;
  }
  table td:last-child {
    border-bottom: 0;
  }
  table td:first-child{
    color:white;
    background: #000;
  }
}
<table>
  <caption>Statement Summary</caption>
  <thead>
    <tr>
      <th scope="col">Account</th>
      <th scope="col">Estimated arrival date</th>
      <th scope="col">Amount</th>
      <th scope="col">Period</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td data-label="Account">Visa - 3412</td>
      <td data-label="Really freaking long div magic">04/01/2016</td>
      <td data-label="Amount">$1,190</td>
      <td data-label="Period">03/01/2016 - 03/31/2016</td>
    </tr>
    <tr>
      <td scope="row" data-label="Account">Visa - 6076</td>
      <td data-label="Due Date">03/01/2016</td>
      <td data-label="Amount">$2,443</td>
      <td data-label="Period">02/01/2016 - 02/29/2016</td>
    </tr>
    <tr>
      <td scope="row" data-label="Account">Corporate AMEX</td>
      <td data-label="Due Date">03/01/2016</td>
      <td data-label="Amount">$1,181</td>
      <td data-label="Period">02/01/2016 - 02/29/2016</td>
    </tr>
</tbody>
</table>

The column header is represented using the data-label attribute on each corresponding table cell. In the CSS, it's called with content: attr(data-label). I'm applying this style to some pretty large tables and I don't want to have to write the data-label for every single cell in the HTML. Is there a way to pull the th into the data-label attribute using Javascript?

Share Improve this question edited May 20, 2021 at 13:17 logi-kal 7,8796 gold badges35 silver badges46 bronze badges asked Nov 3, 2017 at 17:27 kfievelkfievel 211 gold badge1 silver badge2 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Do you want the table to go from this:

| Account | Estimated arrival date | Amount | Period |
| ------- | ---------------------- | ------ | ------ |
|    1234 |             03/15/2001 |  $1.00 |    3rd |
|    1235 |             04/21/2002 | $12.00 |    4th |
|    4594 |             11/11/2011 | $45.00 |    2nd |

To this?:

-----------
Account: 1234
Estimated Arrival Date: 03/15/2001
Amount: $1.00
Period: 3rd
-----------
Account: 1235
Estimated Arrival Date: 04/21/2002
Amount: $12.00
Period: 4th
-----------
Account: 4594
Estimated Arrival Date: 11/11/2011
Amount: $45.00
Period: 2nd
-----------

UPDATE Try this code:

function toggle() {
  var table = document.querySelector('.my-table');
  table.classList.toggle('show-thin');
}
.table {
  border-collapse: collapse;
  display: inline-table;
}

.tr {
  display: table-row;
}

.th, .td {
  display: table-cell;
  border: 1px solid #555;
  padding: 3px 6px;
}

.th {
  background-color: #ddd;
  font-weight: bold;
  text-align: center;
}

.td {
  text-align: right;
}

.my-table.show-thin {
  display: block;
}

.show-thin .tr {
  border-bottom: 1px solid black;
  display: block;
  margin-bottom: 2px;
  padding-bottom: 2px;
}

.show-thin .td {
  border: none;
  display: block;
  padding: 0;
  text-align: left;
}

.show-thin .td:before {
  content: attr(title) ':';
  display: inline-block;
  font-weight: bold;
  padding-right: 5px;
}

.show-thin .thin-hide {
  display: none;
}
<button onclick="toggle()">Toggle</button>
<hr/>
<div class="my-table">
<div class="tr thin-hide">
  <span class="th">Account</span>
  <span class="th">Estimated arrival date</span>
  <span class="th">Amount</span>
  <span class="th">Period</span>
</div>
<div class="tr">
  <span class="td" title="Account">1234</span>
  <span class="td" title="Estimated Arrival Date">03/15/2001</span>
  <span class="td" title="Amount">$1.00</span>
  <span class="td" title="Period">3rd</span>
</div>
<div class="tr">
  <span class="td" title="Account">1235</span>
  <span class="td" title="Estimated Arrival Date">04/21/2002</span>
  <span class="td" title="Amount">$12.00</span>
  <span class="td" title="Period">4th</span>
</div>
<div class="tr">
  <span class="td" title="Account">4594</span>
  <span class="td" title="Estimated Arrival Date">11/11/2011</span>
  <span class="td" title="Amount">$45.50</span>
  <span class="td" title="Period">2nd</span>
</div>
</div>

My example used a class to change the values from a tabular format to a lined format. But it can be done using a media query as well. This was just easier to demo.

The trick is in placing the title attribute on every cell. Then using CSS to show the title when in thin mode.


This shows what the table looks like in wide mode


And this shows what it is like in thin mode


When you look at the two images you will see that the standard table format uses the term "Estimated arrival date" with on the first work capitalized. The thin version uses "Estimated Arrival Date" with all words capitalized. This is to show that the values e from different places.

In the wide mode the header es from here:

<div class="tr thin-hide">
  <span class="th">Account</span>
  <span class="th">Estimated arrival date</span>
  <span class="th">Amount</span>
  <span class="th">Period</span>
</div>

And in thin mode it es from the title attribute.

This does not work if you try to use <table>, <tr>, <th> and <td> tags.

This small code jQuery copy attr "data-label" TH to TD

$('table th').each(function(i,elem) {
  var num = i + 1;
  $('table td:nth-child(' + num + ')').attr('data-label', $(elem).text());
});

My solution with jQuery, seems to work (optional: I skip over any table cells with colspans):

    $('.myDiv table').each(function (index, value) {
    var headerCount = $(this).find('thead th').length;

    for (i = 0; i <= headerCount; i++) {
        var headerLabel = $(this).find('thead th:nth-child(' + i + ')').text();

        $(this).find('tr td:not([colspan]):nth-child(' + i + ')').replaceWith(
            function () {
                return $('<td data-label="' + headerLabel + '">').append($(this).contents());
            }
        );
    }

});
发布评论

评论列表(0)

  1. 暂无评论