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

javascript - Scrolling a table with multiple fixed table headers - Stack Overflow

programmeradmin2浏览0评论

Before I attempt to reinvent the wheel (via jQuery plugin or similar), I'm trying to see if there is an easier way to do this or an existing plugin that users may know of. What I'm looking to do is scroll the body of a table that contains multiple table headers. For example, imagine something of this structure:

<table>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
           <td></td>
           <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

Honestly, I haven't tried out the above syntax to even see if its valid. The actual markup I have does not currently use thead/tbody and instead scrolls the whole parent div (seen below).

What I want to achieve is scrolling of the whole table such that the header of the most relevant section is viewed on top. Currently the header scrolls out of view is there are enough rows.

I know the various techniques used to scroll a table with one header, but what about multiple? Are there any existing ways to achieve this? I'm open to different ideas, but right now I'm thinking of simply displaying the most relevant table header for the content on top.

Before I attempt to reinvent the wheel (via jQuery plugin or similar), I'm trying to see if there is an easier way to do this or an existing plugin that users may know of. What I'm looking to do is scroll the body of a table that contains multiple table headers. For example, imagine something of this structure:

<table>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
    <thead>
        <tr>
            <td colspan="2"></td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
           <td></td>
           <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

Honestly, I haven't tried out the above syntax to even see if its valid. The actual markup I have does not currently use thead/tbody and instead scrolls the whole parent div (seen below).

What I want to achieve is scrolling of the whole table such that the header of the most relevant section is viewed on top. Currently the header scrolls out of view is there are enough rows.

I know the various techniques used to scroll a table with one header, but what about multiple? Are there any existing ways to achieve this? I'm open to different ideas, but right now I'm thinking of simply displaying the most relevant table header for the content on top.

Share Improve this question edited Nov 26, 2016 at 23:42 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Nov 7, 2011 at 22:36 achinda99achinda99 5,0784 gold badges37 silver badges42 bronze badges 4
  • This is a pretty specialized case - It may have been done before, but I doubt you'll find an existing plugin. Are you just looking for answers that point you to an existing plugin, or are you looking for help "inventing the wheel"? – gilly3 Commented Nov 10, 2011 at 17:37
  • 5 here is jquery plugin for sticky header polarblau.github./stickySectionHeaders but it's for 'ul' list not table. This example might help you too jsfiddle/6qqPz – satrun77 Commented Nov 10, 2011 at 22:55
  • @satrun77: Thanks, those actually look really interesting. Might be onto something there. – achinda99 Commented Nov 12, 2011 at 3:00
  • @gilly3: I'm more than willing to invent the wheel if need be, but before I go on that endeavor, I wanted to see if it already has been done. If it has not, ideas for features/functionality are definitely wele. – achinda99 Commented Nov 12, 2011 at 3:01
Add a ment  | 

1 Answer 1

Reset to default 15 +100

A few months ago, I wrote some code that did exactly that where I wanted the headers to perform similar to section headers on iOS. Utilising a Jquery, the solution I ended up with involved creating an onScroll (and onResize for window resizing) event listener that ran a check through all $('table thead') and checked their $(this).position() on the page.

The check was whether the thead had a position which was above the top of the current viewport.

Once I had found the most relevant header (the bottommost thead that was above the viewport), I created a new table, with position: fixed at (0, 0) and copied into it a new column for each column of the headers rows and manually set its width properties to match the original table.

I have put together a Proof of Concept which shows how this all works.

Here is some pseudo-code of how it works:

  1. Check the table is visible
  2. Get a list of all thead sections in the table
  3. Reverse the list
  4. Find the first thead in the array with a top position less than scrollTop of the body element
  5. If we found one:
    1. Create deep copy of the thead
    2. Make a container table
    3. Copy attributes from the original table so the styles get copied
    4. Position the container at [0, originalTable.left]
    5. Set the width equal to the outerWidth of the original table
    6. Set the width of every td found to the width of the matching td from the original table
    7. Add it to the DOM
  6. If none found, remove the existing container from the DOM if there was one

There are some other edge case details that made this even nicer too:

  • Instead of (0, 0), the origin point for the fixed row was altered based upon whether the "real" header row for the tbody below the one with the fixed header should be pushing it away.
  • Ensure that previous header rows are deleted before making a new one
  • Don't recreate the header row if the header you'd be making is the same as what is already there

This approach worked a lot better others I tried such as trying to position:absolute an object due to the fact that Firefox and IE aren't incredibly fast at running the onScroll handler so you tend to see 'juddering'. I also tried mucking with the position attribute of the theads, this just ended in the table column widths jumping about and not matching the data.

thead nodes aren't strictly required for this solution as you can use some other selector to determine which rows are headers etc.


Update: Added example code and pseudo-code Update: Dropbox changed their system, replaced example with jsfiddle URL

发布评论

评论列表(0)

  1. 暂无评论