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

jquery - Using Javascript to resize a div to screen height causes flickering when shrinking the browser window - Stack Overflow

programmeradmin3浏览0评论

The Background:

I tried to solve the StackOverflow question yet another HTML/CSS layout challenge - full height sidebar with sticky footer on my own using jQuery. Because the sidebar in my case may be longer than the main content it matches the case of ment 8128008. That makes it impossible to have a sidebar longer than the main content and having a sticky footer without getting problems when shrinking the browser window.

The status quo:

I have a html page with a div, which is automatically stretched to fill the screen. So if there is empty space below the element, I stretch it downwards:

But if the browser viewport is smaller than the div itself, no stretching is done but the scrollbar shows up:

I've attached jQuery to the window's resize event to resize the div, if the browser window is not to small and remove any resizing in the other case. This is done by checking if the viewport is higher or smaller than the document. If the viewport is smaller than the document, it seems like the content is larger than the browser window, why no resizing is done; in the other case we resize the div to fill the page.

if ($(document).height() > $(window).height()) {
    // Scrolling needed, page content extends browser window
    // --> No need to resize the div
    // --> Custom height is removed
    // [...]
} else {
    // Window is larger than the page content
    // --> Div is resized using jQuery:
    $('#div').height($(window).height());
}

The Problem:

Up to now, everything runs well. But if I shrink the browser window, there are cases, where the div should be resized but the document is larger than the window's height, why my script assumes, that no resizing is needed and the div's resizing is removed.

The point is actually, that if I check the document's height using Firebug after the bug appeared, the height has just the value is was meant to have. So I thought, the document's height is set with a little delay. I tried to run the resize code delayed a bit but it did not help.

I have set up a demonstration on jsFiddle. Just shrink the browser window slowly and you'll see the div "flickering". Also you can watch the console.log() output and you will notice, that in the case of "flickering" the document's height and the window's height are different instead of being equal.

I've noticed this behavior in Firefox 7, IE 9, Chrome 10 and Safari 5.1. Can you confirm it?

Do you know if there is a fix? Or is the approach totally wrong? Please help me.

The Background:

I tried to solve the StackOverflow question yet another HTML/CSS layout challenge - full height sidebar with sticky footer on my own using jQuery. Because the sidebar in my case may be longer than the main content it matches the case of ment 8128008. That makes it impossible to have a sidebar longer than the main content and having a sticky footer without getting problems when shrinking the browser window.

The status quo:

I have a html page with a div, which is automatically stretched to fill the screen. So if there is empty space below the element, I stretch it downwards:

But if the browser viewport is smaller than the div itself, no stretching is done but the scrollbar shows up:

I've attached jQuery to the window's resize event to resize the div, if the browser window is not to small and remove any resizing in the other case. This is done by checking if the viewport is higher or smaller than the document. If the viewport is smaller than the document, it seems like the content is larger than the browser window, why no resizing is done; in the other case we resize the div to fill the page.

if ($(document).height() > $(window).height()) {
    // Scrolling needed, page content extends browser window
    // --> No need to resize the div
    // --> Custom height is removed
    // [...]
} else {
    // Window is larger than the page content
    // --> Div is resized using jQuery:
    $('#div').height($(window).height());
}

The Problem:

Up to now, everything runs well. But if I shrink the browser window, there are cases, where the div should be resized but the document is larger than the window's height, why my script assumes, that no resizing is needed and the div's resizing is removed.

The point is actually, that if I check the document's height using Firebug after the bug appeared, the height has just the value is was meant to have. So I thought, the document's height is set with a little delay. I tried to run the resize code delayed a bit but it did not help.

I have set up a demonstration on jsFiddle. Just shrink the browser window slowly and you'll see the div "flickering". Also you can watch the console.log() output and you will notice, that in the case of "flickering" the document's height and the window's height are different instead of being equal.

I've noticed this behavior in Firefox 7, IE 9, Chrome 10 and Safari 5.1. Can you confirm it?

Do you know if there is a fix? Or is the approach totally wrong? Please help me.

Share Improve this question edited May 23, 2017 at 10:30 CommunityBot 11 silver badge asked Oct 16, 2011 at 16:34 msiemensmsiemens 2,2931 gold badge28 silver badges38 bronze badges 9
  • 2 Very well formatted question. +1 – Akos Commented Oct 16, 2011 at 16:39
  • A little off-topic, but you're passing jQuery as an argument to your self-invoking function, whilst that function does not accept any arguments. – pimvdb Commented Oct 16, 2011 at 16:41
  • 3 I played around a little, is this anything close to what you want? jsfiddle/2yKgQ/25 – Esailija Commented Oct 16, 2011 at 16:48
  • @Esailija -- i might be wrong, but wouldn't the use of timeouts here be a detriment to page performance? On every resize there's a timeout? Although it works, it's a kind of like using a hand grenade to kill a mosquito. Check out my answer below, there's a much simpler solution (perhaps) – tmsimont Commented Oct 16, 2011 at 17:06
  • It should increase performance as the browser doesn't need to calculate overflow after every single resize but only after every resize session (the resize session is 150 milliseconds long). And there is only one timeout active at a time, I am not 100% sure but it's the amount of concurrent timers active that degrade performance, not resetting one timer? jQuery launches a new timeout internally every 13 milliseconds after all :P – Esailija Commented Oct 16, 2011 at 17:27
 |  Show 4 more ments

3 Answers 3

Reset to default 6

Ok -- wiping my old answer and replacing...

Here's your problem:

You are taking and paring window and document height, without first taking into consideration the order of events here..

  1. Window loads
  2. Div grows to window height
  3. Window shrinks
  4. Document height remains at div height
  5. Window height is less than div height

At this point, the previously set height of the div is keeping document height greater than the window height, and this logic is misinterpreted: "Scrolling needed, no need to extend the sidebar" fires, erroneously

Hence the twitch.

To prevent it, just resize your div along with the window before making the parison:

(function () {
    var resizeContentWrapper = function () {
            console.group('resizing');


            var target = {
                content: $('#resizeme')
            };

            //resize target content to window size, assuming that last time around it was set to document height, and might be pushing document height beyond window after resize
        //TODO: for performance, insert flags to only do this if the window is shrinking, and the div has already been resized
            target.content.css('height', $(window).height());

            var height = {
                document: $(document).height(),
                window: $(window).height()
            };

            console.log('height: ', height);


            if (height.document > height.window) {
                // Scrolling needed, no need to externd the sidebar
                target.content.css('height', '');

                console.info('custom height removed');
            } else {
                // Set the new content height
                height['content'] = height.window;
                target.content.css('height', height['content']);

                console.log('new height: ', height);
            }
            console.groupEnd();
        }
    resizeContentWrapper();
    $(window).bind('resize orientationchange', resizeContentWrapper);
})(jQuery);

Per pmvdb's ment, i renamed your $$ to "target"

$(window).bind('resize',function(){
    $("#resizeme").css("height","");

    if($("#resizeme").outerHeight() < $(window).height()){
       $("#resizeme").height($(window).height());
       $("body").css("overflow-y","hidden");  
    }else{
       $("body").css("overflow-y","scroll");  
    }           
});

Maybe I am misunderstanding the problem, but why are you using Javascript? This seems like a layout (CSS) issue. My solution without JS: http://jsfiddle/2yKgQ/27/

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论