views:

55

answers:

2

Hi,

I have a table, representing a calendar, that can expand and collapse table rows.

  <tr class="parent" id="month1">
    <th class="subheader">Januari</th>
    <th></th><th></th>
  </tr>
  <tr class="row child-month1" id="day-1">
    <td class="date"> 1 januari 2010</td>
    <td>Bedrag </td>
    <td>-817.0 </td>
  </tr>
  <tr class="row child-month1" id="day-2">
    <td class="date"> 2 januari 2010</td>
    <td>Bedrag </td>
    <td> 0 </td>
  </tr>

With jQuery I make it clickable:

<script type="text/javascript">
$(document).ready(function() {    
  $('tr.parent').click(function(){
    $(this).siblings('.child-' + this.id).toggle();
    return false;
  });
});
</script>

The problem now, is that the window scrolls always to the top after a table row is clicked. I want it to stay at the scrolling position that it was before the click.

The child rows get collapsed as supposed to, but the document scrolls to the top immediately after the click, even though i have returned false at the end of .click... What am I doing wrong?

Thanks in advance!

A: 

Even if you didn't return false in the click handler, the page shouldn't be scrolling in response to the click.

Is it perhaps that the page is short enough that when some of the rows collapse, the page gets enough shorter that it all fits within the viewport? (And so naturally the browser scrolls up to fill the viewport.)

Update And if that's the case, you might consider trying to preserve scrollTop during the call:

$(document).ready(function() {    
  $('tr.parent').click(function(){
    var scrollTop = document.body.scrollTop;        // <== Save the current value
    // *** Maybe append something to the page here to keep it tall***
    $(this).siblings('.child-' + this.id).toggle();
    // *** Maybe remove the appended thing now ***
    document.body.scrollTop = scrollTop;            // <== Restore it
    return false;
  });
});

If all of this is in a container other than body, you may need to try to preserve it in that container instead, but you get the idea. This may not be perfect depending on how much the height of the page has changed, but it may help.

T.J. Crowder
Yes, this is the case. But even though it fits in the viewport, doesn't mean it should scroll up IMHO. This conflicts with my unobtrusive way of working...
Wouter Raemaekers
@Wouter: What I mean is, if it doesn't fit (e.g., there are scrollbars showing) and you've moved down (so the scrollTop > 0), when the rows contract the standard behavior of the browser is to put everything in the viewport (of course).
T.J. Crowder
@Wouter: I've added a note about `scrollTop`, which may help.
T.J. Crowder
Thanks TJ for your help. I love this site man. The scrollTop solution appears to be working, but now there is a short flash when the document (tries) to scroll up, and then down again. Is there a way to prevent the short flash of scrolling up?
Wouter Raemaekers
@Wouter: You could append something to the end of the page to ensure that it always stays tall enough to prevent the scrolling entirely (and then remove it when you're done). I've added comments where you might do that.
T.J. Crowder
A: 

Ok so I tried TJ's suggestions to solve the problem.

I changed 'var scrollTop = document.body.scrollTop' to 'var scrollTop = window.pageYOffset' because somehow document.body.scrollTop always returns 0 (don't know why). the pageYOffset returns the correct scroll position for me. I did all this in Firefox by the way.

I ended up with this code:

  <div id="bottomspacer" style="height: 1000px; display: none; "></div>
  <script type="text/javascript">
  $('tr.parent').click(function(){
    $('#bottomspacer').show();
    var scrollTop = window.pageYOffset;
    $(this).siblings('.child-' + this.id).toggle();
    document.body.scrollTop = scrollTop;
    $('#bottomspacer').hide();
    return false;
  });
  </script>
Wouter Raemaekers