admin管理员组

文章数量:1335096

I am trying to implement a calendar list view like the iOS one. Basically, what I am doing now is to loop through my array of events. If it is a new date, print a date header, else print the calendar event. I want to make the DATE HEADER rows sticky until they get "scrolled away".

How can I achieve that? I see lots of examples on sticky headers but there's no actual one that applies this "sticky" feature to table rows only. My <table is also put within its own scrollable fixed height and I want the header to stick at the top of the <div> instead of at top:0;

I have put my code into a pen at and now I am left with fixing the colspan because my <td> doesnt span across the cells, and getting the <tr> to stick at the top of the <div>.

I am trying to implement a calendar list view like the iOS one. Basically, what I am doing now is to loop through my array of events. If it is a new date, print a date header, else print the calendar event. I want to make the DATE HEADER rows sticky until they get "scrolled away".

How can I achieve that? I see lots of examples on sticky headers but there's no actual one that applies this "sticky" feature to table rows only. My <table is also put within its own scrollable fixed height and I want the header to stick at the top of the <div> instead of at top:0;

I have put my code into a pen at http://codepen.io/anon/pen/zxpkr and now I am left with fixing the colspan because my <td> doesnt span across the cells, and getting the <tr> to stick at the top of the <div>.

Share Improve this question edited Jul 17, 2013 at 0:57 000 27.3k10 gold badges74 silver badges103 bronze badges asked Jul 8, 2013 at 17:10 chongzixinchongzixin 1,9794 gold badges30 silver badges57 bronze badges 7
  • Any html - css - javascript code to provide ? Also, your codepen example is NOT about table. Those are dividers. div's. Anyway, go take a look at : imakewebthings./jquery-waypoints/shortcuts/sticky-elements – Milche Patern Commented Jul 8, 2013 at 17:18
  • You can also take a look at : stackoverflow./questions/9590087/… – Milche Patern Commented Jul 8, 2013 at 17:24
  • Yeah I realised my tags (div and table and tr and td) didnt show initially until I enclosed them in code tags. – chongzixin Commented Jul 9, 2013 at 2:37
  • @user1258600 Your issue is a Client Side issue, so you have to supply your PHP's HTML output in your code example. Modify this jsfiddle example and jsfiddle/dCKmL – SaidbakR Commented Jul 10, 2013 at 22:48
  • @sємsєм my code is now on CodePen @ codepen.io/anon/pen/zxpkr ! :) – chongzixin Commented Jul 11, 2013 at 13:57
 |  Show 2 more ments

3 Answers 3

Reset to default 2

I had to wrap the scrollable div with a container div and play with the if statements a bit, but it works.

Working Example

JS

function stickyTitles(stickies) {
    this.load = function () {
        stickies.each(function () {
            var thisSticky = jQuery(this).wrap('<div class="followWrap" />');
            thisSticky.parent().height(thisSticky.outerHeight());
            jQuery.data(thisSticky[0], 'pos', thisSticky.offset().top);
        });
    };
    this.scroll = function () {
        stickies.each(function (i) {
            var thisSticky = jQuery(this),
                nextSticky = stickies.eq(i + 1),
                prevSticky = stickies.eq(i - 1),
                pos = jQuery.data(thisSticky[0], 'pos'),
                h = $('.mytable').offset().top;
            if (pos <= jQuery('.mytable').scrollTop() + h) {
                thisSticky.addClass("fixed");
                if (nextSticky.length > 0 && jQuery('.mytable').scrollTop() + h >= jQuery.data(thisSticky[0], 'pos') - prevSticky.outerHeight()) {
                    thisSticky.addClass("absolute").css("top", jQuery.data(nextSticky[0], 'pos') - $('.mytable').scrollTop() - prevSticky.outerHeight() - h);
                }
            } else {
                thisSticky.removeClass("fixed");
                if (prevSticky.length > 0 && jQuery('.mytable').scrollTop() + h <= jQuery.data(thisSticky[0], 'pos') - prevSticky.outerHeight()) {
                    prevSticky.removeClass("absolute").removeAttr("style");
                }
            }
        });
    };
}
jQuery(document).ready(function () {
    var newStickies = new stickyTitles(jQuery(".followMeBar"));
    newStickies.load();
    jQuery('.mytable').on("scroll", function () {
        newStickies.scroll();
    });
});

CSS

body {
    height:2000px;
    margin: 0;
    background: #333;
    color: #fff;
    overflow: auto;
}
table {
    width: 100%;
}
table tr {
    height: 100px;
}
.followMeBar {
    display: block;
    background: #222;
    border-bottom: solid 1px #111;
    border-top: solid 1px #444;
    position: relative;
    z-index: 1;
    width: 200%;
}
.followMeBar.fixed {
    position: absolute;
    top: 0;
    width: 90%;
    z-index: 0;
}
.followMeBar.fixed.absolute {
    position: absolute;
}
.mytable {
    overflow-y: scroll;
    height: 250px;
}
#hidden {
    overflow:hidden;
    position:absolute;
    width:100%;
}

HTML

<h1>Test</h1>

<p>My table in a div below...</p>
<div id="hidden">
    <div class='mytable'>
        <table>
            <tr class='followMeBar'>
                <td colspan="4">12-07-2013</td>
            </tr>
            <tr>
                <td>4:35 PM</td>
                <td>1729</td>
                <td>2</td>
                <td>jack</td>
            </tr>
            <tr>
                <td>4:40 PM</td>
                <td>KSKS</td>
                <td>4</td>
                <td>jason</td>
            </tr>
            <tr>
                <td>5:35 PM</td>
                <td>1714</td>
                <td>4</td>
                <td>raymond</td>
            </tr>

        etc...

        </table>
    </div>
</div>

Please note that this method was based off of this answer, I had to adjust things a bit to make it work for a scrollable div, but I want to give credit where credit is due.

Replaced all divs with a table and trs, added some styling, and it works :P

Code: Codepen

Altough it wraps up all header trs with a div. It's not really allowed by the specs but it works.

Instead of making a row absolute position, which btw may not work very well across browsers, I would rather have a table at the top which works as the table head (and sticks to the top of the parent div) and have the data table scroll below it.

You dont even need to use jQuery for this!

http://jsbin./ucevuy/1/edit

* {
  margin:0;
  padding:0;
}
div {
  border:solid red;
  height:300px;
  overflow:auto;
}
table {
  width:400px;
}
td {
  border:solid black 1px;
  width:50%;
}
.head {
  position:absolute;
  top:0;
  background-color:#fff;
}

.data {
  margin-top:20px;
}

本文标签: javascriptSticky table rowsStack Overflow