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

javascript - Sticky headers not maintaining width when scrolling - Stack Overflow

programmeradmin3浏览0评论

I have some table headers which I planned on making sticky (fixed) as the user scrolls down the page, but they currently shrink when the sticky is activated, I would like them to inherit the widths of the headers, but they shrink to the size of the text at the moment. My JS:

$(document).ready(function() {  
var stickyNavTop = $('.th').offset().top;

SOLUTION:

 $(".th th").each(function(){$(this).width($(this).width());});
 $('.th').width($('.th').width());

var stickyNav = function(){  
var scrollTop = $(window).scrollTop();  

if (scrollTop > stickyNavTop) {   
    $('.th').addClass('sticky');  
} else {  
    $('.th').removeClass('sticky');   
}  
};  

stickyNav();  

$(window).scroll(function() {  
    stickyNav();  
});  
});  

My HTML:

<table class="mGrid" cellspacing="0" rules="all" border="1" id="1"
style="width:98%;border-collapse:collapse;">
  <tr class="th">
    <th scope="col">Membership No.</th>
    <th scope="col">Surname</th>
    <th scope="col">Other Name(s)</th>
  </tr>
  <tr>
    <td>
      <div id="2" class="formInput">
        <label for="2">Membership No.</label>
        <input name="2" type="text" value="AH6973" id="2"
        class="required" style="width:60px;" />
      </div>
    </td>
    <td>
      <div id="3" class="formInput">
        <label for="3">Surname</label>
        <input name="3" type="text" value="CARTER" id="3"
        style="width:100px;" />
      </div>
    </td>
    <td>
      <div id="4" class="formInput">
        <label for="4">Other Name(s)</label>
        <input name="4" type="text" value="RAYMOND" id="4"
        style="width:150px;" />
      </div>
    </td>
  </tr>
</table>

my CSS:

.sticky {
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 100;
    border-top: 0;
    color: #fff !important;
    background: #666;
    border-left: solid 1px #525252;
    font-size: 1.0em;
}

(This is modelled to be the same as the header style, it's just the width shrinks to fit the width of the text at the moment. I tried to edit the header style but it's apparently read-only "'HeaderStyle' property is read-only and cannot be set."

I have some table headers which I planned on making sticky (fixed) as the user scrolls down the page, but they currently shrink when the sticky is activated, I would like them to inherit the widths of the headers, but they shrink to the size of the text at the moment. My JS:

$(document).ready(function() {  
var stickyNavTop = $('.th').offset().top;

SOLUTION:

 $(".th th").each(function(){$(this).width($(this).width());});
 $('.th').width($('.th').width());

var stickyNav = function(){  
var scrollTop = $(window).scrollTop();  

if (scrollTop > stickyNavTop) {   
    $('.th').addClass('sticky');  
} else {  
    $('.th').removeClass('sticky');   
}  
};  

stickyNav();  

$(window).scroll(function() {  
    stickyNav();  
});  
});  

My HTML:

<table class="mGrid" cellspacing="0" rules="all" border="1" id="1"
style="width:98%;border-collapse:collapse;">
  <tr class="th">
    <th scope="col">Membership No.</th>
    <th scope="col">Surname</th>
    <th scope="col">Other Name(s)</th>
  </tr>
  <tr>
    <td>
      <div id="2" class="formInput">
        <label for="2">Membership No.</label>
        <input name="2" type="text" value="AH6973" id="2"
        class="required" style="width:60px;" />
      </div>
    </td>
    <td>
      <div id="3" class="formInput">
        <label for="3">Surname</label>
        <input name="3" type="text" value="CARTER" id="3"
        style="width:100px;" />
      </div>
    </td>
    <td>
      <div id="4" class="formInput">
        <label for="4">Other Name(s)</label>
        <input name="4" type="text" value="RAYMOND" id="4"
        style="width:150px;" />
      </div>
    </td>
  </tr>
</table>

my CSS:

.sticky {
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 100;
    border-top: 0;
    color: #fff !important;
    background: #666;
    border-left: solid 1px #525252;
    font-size: 1.0em;
}

(This is modelled to be the same as the header style, it's just the width shrinks to fit the width of the text at the moment. I tried to edit the header style but it's apparently read-only "'HeaderStyle' property is read-only and cannot be set."

Share Improve this question edited Mar 3, 2014 at 11:24 Baranitharan Selvasundaram 1402 silver badges11 bronze badges asked Feb 14, 2014 at 14:46 Ed HarrodEd Harrod 3,6294 gold badges34 silver badges56 bronze badges 4
  • 2 We don't want your ASP, we want your resulting HTML markup... this is front end stuff my friend. – Alvaro Commented Feb 14, 2014 at 15:18
  • 1 Anyway I believe that's not possible. I tried it once. I would remend you to create an absolute positioned element on scrolling at the top of the page. – Alvaro Commented Feb 14, 2014 at 15:21
  • Hi Alvaro, I've replaced the .aspx with the HTML now, I thought it would be difficult to do but didn't think it was impossible! – Ed Harrod Commented Feb 14, 2014 at 15:41
  • Well, as I said, I would do an an absolute positioned element instead of trying to break the table. The position fixed that you are trying to apply will break any connection with the table and therefore you will need to apply styles to acmodate it to the table structure, which is... like creating the element i suggested. – Alvaro Commented Feb 14, 2014 at 15:50
Add a ment  | 

3 Answers 3

Reset to default 6

Just add this line before your function definition:

$('th').width($('th').width());

Full JavaScript code:

$(document).ready(function() {  
    var stickyNavTop = $('.th').offset().top;  

    $('th').width($('th').width());

    var stickyNav = function(){  
        var scrollTop = $(window).scrollTop();
        if (scrollTop > stickyNavTop) {   
            $('.th').addClass('sticky');  
        } else {  
            $('.th').removeClass('sticky');   
        }  
    };  

    stickyNav();  

    $(window).scroll(function() {  
        stickyNav();  
    });  
});

here is a mon solution, it auto detects each sub-element's width and height and reflect when scrolling, it is something like following:

var $this = $(this),
      top = $this.offset().top,
      left = $this.offset().left,
      width = $this.width(),
      height = $this.height(),
      widthArr = [],
      heightArr = [];
    $this.find("*").each(function(i, e) {
      widthArr.push($(this).width());
      heightArr.push($(this).height());
    });

$(window).scroll(function() {
  if($(window).scrollTop() >= top) {
    $this.css({
      position: "fixed",
      top: 0,
      left: left,
      "z-index": 100,
      width: width,
      height: height
    });

    $this.find("*").each(function(i, e) {
      $(this).width(widthArr[i]);
      $(this).height(heightArr[i]);
    });
  } else {
      // to be implemented
  }
});

My solution to avoid column width changes : cloning the header. (Thanks to @Matt for the line: $('th').width($('th').width()); and his solution.)

JS

var stickyNavTop = jQuery('thead tr:first-child').offset().top;

// init state
var stickState = (jQuery(window).scrollTop() > stickyNavTop);

var stickyNav = function() {
    var scrollTop = jQuery(window).scrollTop();

    // state has changed?
    if (stickState != (scrollTop > stickyNavTop)) {

        // remember/catch new state
        stickState = (scrollTop > stickyNavTop);

        if (stickState) {  
            jQuery('thead tr:first-child th').each(
                function() { jQuery(this).width( jQuery(this).width() ); }
            );

            // cloning the header : the original columns won't move
            jQuery('thead tr:first-child')
                .clone()
                .prependTo(jQuery('thead'))
                .addClass('sticky');

        } else {  
            jQuery('tr.sticky').remove();
        }  

    }
};  

jQuery(window).scroll(function() { 
    stickyNav();  
});  

stickyNav();

CSS

.sticky {
    position: fixed;
    top: 0;
    z-index: 100;
}
发布评论

评论列表(0)

  1. 暂无评论