jquery偏移顶部错误值,但在页面调整大小时正确

时间:2016-07-03 18:26:43

标签: javascript jquery offset sticky window-resize

我想实现一个粘性菜单,如本页左侧导航:http://getbootstrap.com/2.3.2/scaffolding.html

我的菜单是一个nav元素position:relative(我也试过了staticfixed当它到达视口的顶部时。{/ p>

这是我的职责:

$(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

console.log(elementPosition);在页面加载时返回大约1200px的偏移量顶部,这是错误的。但是如果我调整页面大小,则值会变为650px左右,这是正确的偏移顶部,并且函数会执行它应该执行的操作。

我环顾四周,发现当它隐藏元素时,offsetp top可能是错误的,或者它有边距问题但我实际上并没有任何复杂的结构,只是一个单个可见的nav元素。

任何有关解决这个问题的帮助都将非常感谢!谢谢!

2 个答案:

答案 0 :(得分:3)

当DOM准备好时,会发生

jQuery(document).ready处理程序。不是在页面完全呈现时。

https://api.jquery.com/ready/

  

使用依赖CSS样式属性值的脚本时,   引用外部样式表或嵌入样式很重要   在引用脚本之前的元素。

     

在代码依赖于加载的资产的情况下(例如,如果   图像的尺寸是必需的),代码应放在一个   改为加载事件的处理程序。

因此,如果您正在使用在相关脚本之后加载的样式表,或者页面布局取决于图像大小或其他内容,那么当页面为ready时,将会遇到load事件。不处于最终渲染状态。

你可以通过以下方式解决这个问题:

  1. 确保在脚本
  2. 之前包含所有样式表
  3. 确保CSS更强大,并且不太依赖于内容大小(例如图像)
  4. 或者,您可以在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(); }); 事件窗口上执行此操作。
  5. 编辑:

    如果要使脚本依赖于多个异步事件(如loadCSS库),请使用:

    COND

答案 1 :(得分:-1)

您可以通过在文档中设置显示测试元素的样式标记来添加检查以查看您的CSS是否已加载,然后在CSS文件中覆盖它以隐藏它。然后,您可以通过选中此元素来检查页面的状态。例如......

在您的HTML中:

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

在你的CSS中:

#loaded-check { display:none; }

在你的jQuery脚本中:

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
}