jQuery粘性div行为不端

时间:2011-06-27 11:07:25

标签: javascript jquery

我正在使用一些代码来保持侧边栏元素在视图中(并在其父级的范围内),同时滚动并且遇到一些问题。我在一个页面上有大量文章(大约10个),每个文章都有自己的侧边栏。标记看起来像这样:

<article>
    <section class="project-details entry-content">
        <header>
            ...
        </header>
    </section>
    <section class="offset-by-four twelve columns">
        ...
    </section>
</article>

CSS:

article {
    padding-top: 2em;
    position: relative; }
article .project-details {
    margin: 0 10px;
    position: absolute;
    width: 220px; }

...最后,Javascript:

$.fn.persistent = function(options) {
    var opts = $.extend({
        duration: 0,
        lockBottom: true
    },
    options),
    elements = [];

    this.each(function() {
        var parentPaddingTop = parseInt($(this).parent().css('paddingTop'));
        $(this).data({
            'parentPaddingTop': parentPaddingTop,
            'startOffset': $(this).parent().offset().top
        }).css({
            position: 'absolute'
        });
        if (opts.lockBottom) {
            var bottomPos = $(this).parent().height() - $(this).height() + parentPaddingTop;
            if (bottomPos < 0) {
                bottomPos = 0;
            }
            $(this).data('bottomPos', bottomPos);
        }
        elements.push($(this));
    });
    $(window).scroll(function() {
        var pastStartOffset = $(document).scrollTop() > opts.startOffset;
        $.each(elements,
            function() {
                var parentPaddingTop = $(this).data('parentPaddingTop'),
                    startOffset = $(this).data('startOffset'),
                    bottomPos = $(this).data('bottomPos');
                $(this).stop();
                var objFartherThanTopPos = $(this).offset().top > startOffset,
                    objBiggerThanWindow = $(this).outerHeight() < $(window).height();
                if ((pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow) {
                    var newpos = ($(document).scrollTop() - startOffset + parentPaddingTop);
                    if (newpos > bottomPos) {
                        newpos = bottomPos;
                    }
                    if ($(document).scrollTop() < startOffset) {
                        newpos = parentPaddingTop;
                    }
                    $(this).animate({
                        top: newpos
                    }, opts.duration);
                }
            }
        );
    });
};

.project-details DIV应该保持粘性,但由于某种原因,只有页面上的第一个有效,其余的则什么都不做。有时第二个会在向下滚动页面时开始工作,然后在中途失败。

任何人都可以看到此代码可能导致此类行为的明显缺陷吗?

1 个答案:

答案 0 :(得分:0)

检查以下代码并确保您了解n是每个元素,使用此代码,如果有意义,则每个函数都不引用当前元素。

 this.each(function(i,n) {
        var parentPaddingTop = parseInt($(n).parent().css('paddingTop'));
        $(n).data({
            'parentPaddingTop': parentPaddingTop,
            'startOffset': $(n).parent().offset().top
        }).css({
            position: 'absolute'
        });
        if (opts.lockBottom) {
            var bottomPos = $(n).parent().height() - $(n).height() + parentPaddingTop;
            if (bottomPos < 0) {
                bottomPos = 0;
            }
            $(n).data('bottomPos', bottomPos);
        }
        elements.push($(n));
    });