views:

206

answers:

7

I have a div with is replaced upon certain user actions. These actions are performed under the div that is being replaced and in the case that the div is too large to fit completely into the view window, along with the buttons used to change it underneath, the browser will jump to the top of the newly loaded div. Which is annoying.

Does anyone know of a way to stop these? Cheers.

Here is the jQuery code. ChartContent is a small blob of html

function UpdateChartImage(ChartContent) {
//do updates on div here 
    var existingChart = $("#" + $(ChartContent).attr("id"));
    existingChart.fadeOut("fast", function() { existingChart.replaceWith(ChartContent); }).fadeIn("fast");
}

Incidentally I have prevented the button from doing it's default behaviour so I don't think it's related to that.

A: 

It seems like your page is reflowing during the content update, so before you do the update, get the container's $.width() and $.height() and set them to those values with $.css(). This will stop the container from moving during content changes.

Alex Sexton
which container? I want to stop the browser view window from jumping up to the top of the newly added content. Not the div moved?
Damien
A: 

If I have understand what you mean, you may need to store the body scroll position to a temporary variable before doing the update then set the stored scroll to the body after.

window.st = document.body.scrollTop;
window.sl = document.body.scrollLeft;

//do updates on div here

document.body.scrollTop = window.st;
document.body.scrollLeft = window.sl;

EDIT:

If you are using jquery's event handlers try returning false on those events, this may stops page from jumping at the top.

$('#item').click (function () {  
    // stuff here  
    return false;//prevent page from jumping at the top when long page items are rendered
});
jerjer
Why do you use the window (aka global space) for your vars? This is bad practice, just define them with "var st = ..."
Tim Büthe
A: 

Are you doing something like this?

<a href="#" onclick="[your jQuery call]">

The href="#" part will make your page jump to the top when the link is clicked.

truppo
nah it's not the event thing. This occurs in another javascript method. I have event.preventDefault in the event function for a button press.
Damien
+1  A: 

This is what happens when you run the code:

The div element is being gradually hidden. When the fadeOut completes it is completely hidden (display set to none). The browser adjusts the page's height and jumps to the end of it. Then the new div is fading in. The browser doesn't do any jumping - it stays where it was before. To you it appears that after the fadeIn it has jumped to the top of the newly added div. Set the animation speed to slow to understand better what is going on.

I believe that the easiest way to solve your problem is to use absolute positioning for the buttons that trigger the animation. Do the old and the new div have the same height? If yes, it will be very easy to calculate the top position of the buttons.

kgiannakakis
+2  A: 

I had a similar problem on a different scenario. If the body's start-height is equal or superior to the body's end-height no problem. If it goes the other way round the view port will jump to the screen top. What I did was to calculate the body's end-height and pre-set it before the content came in. I grabbed your example and put-it into a semi-functional html page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; 
<html xmlns="http://www.w3.org/1999/xhtml"&gt; 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script>
    function UpdateChartImage(ChartContent) {
        //do updates on div here
        var existingChart = $("#content");
        existingChart.fadeOut("fast", function() { 
            existingChart.html(ChartContent);

            // sets body's height to match the end-height
            $(document.body).height($(document.body).height());
        }).fadeIn("fast");
    }

    $(function() {
        $('#div_change').click(function(){
        UpdateChartImage("asdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshadasdkaskdh asdkjhasdkh asdkhas daskdhaskdh asdkhasdkjshad")
        })
    });
</script>
</head> 

<body style="padding: 0; margin: 0;"> 
    <div id="header" style="height: 200px; background-color: #0FF;">this is the header</div>
    <div id="content" style=""></div>
    <div id="footer" style="height: 200px; background-color: #ced;">this is the footer</div>
    <a id="div_change">click me to change the body's div content</a>
</body>
</html>

Hope it helps!

Frankie
This has almost done it! Although the first time I run the function it fails to work. Afterwards, no problem.
Damien
@Damien That would mean the problem is, in fact, similar to the one I had. I can't really tell why it's not working on the first-run without some code from you. Perhaps you can post a demo page somewhere. And, does it happen in all browsers or are you having problems with just one specific flavor?
Frankie
Seems to have stopped! odd. Cheers
Damien
A: 

This isn't easy to answer with the little info you've given. A complete example would help a lot to get the help you want.

Anyway, I suspect either of these:

  1. You have anchors (that truppo mentioned) and preventDefault is not supported for the event that is triggered, or you prevent it the wrong way. Try return false in the event callback, onclick/on[event] attribute, or remove the anchors completely to see if it makes any difference. It would be useful if you could show us how you bind your event, and the html of the element you are binding it to.
  2. You have scripts in the content you load, that cause the page to scroll. "included script tags are evaluated when inserted in the DOM" (http://docs.jquery.com/Ajax/jQuery.ajax#options)
gregers
A: 

I have had this problem as well, and I found the solution being so easy it was hard to figure if out, at least for my case.

Try adding another div around the div you are updating and set it to position:relative;

This worked for me. Of course content bellow will still jump if the content changes size but scroll bar wont jump up to top of page.

Example:

<div style="position: relative;">
  <div id="ajax_update">
    //This is what jQuery will update.
  </div>
</div>
jamietelin