javascript - jquery offset top wrong value, but gets right on page resize - Stack Overflow

I want to achieve a sticky menu like the left navigation on this page: .3.2scaffolding.html.My menu is

I want to achieve a sticky menu like the left navigation on this page: .3.2/scaffolding.html.

My menu is a nav element with position:relative (I tried static as well) that goes fixed when it reaches the top of the viewport.

here's my function:

$(document).ready(function() {
    function stickyNav() {
        var elementPosition = $('nav').offset();
        console.log(elementPosition);

        $(window).scroll(function(){
            if($(window).scrollTop() > elementPosition.top){
                $('nav').addClass("sticky");
            } else {
                $('nav').removeClass("sticky");
            }
        });
    }
    stickyNav();
}); //document ready

the console.log(elementPosition); returns an offset top of around 1200px on page load, which is wrong. But if i resize the page, the value changes to around 650px which is the correct offset top and the function does what it is supposed to be doing.

I've looked around and found out that offsetp top maybe wrong when it's on hidden elements, or it has issues with margins but I actually don't have any plex structure here, just a single visible nav element .

any help on figuring this out would be much appreciated! thanks!!

I want to achieve a sticky menu like the left navigation on this page: http://getbootstrap./2.3.2/scaffolding.html.

My menu is a nav element with position:relative (I tried static as well) that goes fixed when it reaches the top of the viewport.

here's my function:

$(document).ready(function() {
    function stickyNav() {
        var elementPosition = $('nav').offset();
        console.log(elementPosition);

        $(window).scroll(function(){
            if($(window).scrollTop() > elementPosition.top){
                $('nav').addClass("sticky");
            } else {
                $('nav').removeClass("sticky");
            }
        });
    }
    stickyNav();
}); //document ready

the console.log(elementPosition); returns an offset top of around 1200px on page load, which is wrong. But if i resize the page, the value changes to around 650px which is the correct offset top and the function does what it is supposed to be doing.

I've looked around and found out that offsetp top maybe wrong when it's on hidden elements, or it has issues with margins but I actually don't have any plex structure here, just a single visible nav element .

any help on figuring this out would be much appreciated! thanks!!

Share Improve this question edited Jul 3, 2016 at 18:46 valerio0999 asked Jul 3, 2016 at 18:26 valerio0999valerio0999 12.2k7 gold badges32 silver badges57 bronze badges 3
  • Where is stickyNav() called in your code as I don't see an invocation of it? Can you share the html for the nav tag that produces this issue? – Dennis Shtatnov Commented Jul 3, 2016 at 18:42
  • @DennisShtatnov updated, thanks – valerio0999 Commented Jul 3, 2016 at 18:46
  • Here is a minimally functioning example of your code working: jsfiddle/b4m3swhp/1. I'd suspect it is something to do with the structure of where <nav> is being placed or when it was inserted. If a resize is fixing it then it may be possible that some of your css is responsive and effecting the <nav> tag when the screen is a particular width. – Dennis Shtatnov Commented Jul 3, 2016 at 19:08
Add a ment  | 

2 Answers 2

Reset to default 3

jQuery(document).ready handler occurs when the DOM is ready. Not when the page is fully rendered.

https://api.jquery./ready/

When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.

In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead.

So if you're using stylesheets that are loaded AFTER the script in question, or the layout of the page depends on image sizes, or other content, the ready event will be hit when the page is not in its final rendering state.

You can fix that by:

  1. Making sure you include all stylesheets before the script
  2. Making sure the CSS is more robust, and doesn't depend that much on content size (such as images)
  3. Or, you can do this on window load event.

Edit:

If you want to make your script dependent on more than one async event (like the loadCSS library), use this:

var docReady = jQuery.Deferred();
var stylesheet = loadCSS( "path/to/mystylesheet.css" );
var cssReady = jQuery.Deferred();
onloadCSS( stylesheet, function() {
    cssReady.resolve();
});
jQuery(document).ready(function($) {
    docReady.resolve($);
});
jQuery.when(docReady, cssReady).then(function($) {
    //define stickyNav

    stickyNav();
});

You can add a check to see if your CSS has loaded by setting a style tag in your document which shows a test element, and then overwrite this in your CSS file to hide it. Then you can check the status of your page by checking this element. For example...

In your HTML:

<div id="loaded-check" style="display:block; height:10px; width:10px; position:fixed;"></div>

In your CSS:

#loaded-check { display:none; }

In your jQuery script:

var startUp = function() {
    var cssLoaded = $('#loaded-check').is(':visible');
    if (cssLoaded) {
        $('#loaded-check').remove();
        doOtherStuff()
    }
    else {
        setTimeout(function() {
            startUp();
        }, 10);
    }
}

var doOtherStuff = function () {
    //bind your sticky menu and any other functions reliant on DOM load here
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745265792a4619447.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信