2011-06-27 11 views
0

私は、スクロール中にサイドバー要素をビュー(およびその親の境界内)に保つために少しのコードを使用していますが、少し問題があります。私はページ上に複数の記事(約10件)を持っており、それぞれにはサイドバーがあります。jQuery sticky div misbehaving

<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だが、マークアップは次のようになります何らかの理由でページの最初のものだけが機能し、残りのものは何もしません。場合によっては、ページをスクロールしながら2番目のページが機能し始め、途中で失敗することがあります。

誰もこのような動作を引き起こす可能性のあるこのコードで目障りな欠陥を見ることができますか?

+0

http://imakewebthings.github.com/jquery-waypoints/sticky-elements/ ..あなたが再び最初からそれを実行する必要があります...自分自身にいくつかの時間を節約... – Val

+0

たりしないでください'返す$ .each(elements、....'と 'return this.each ....'チェーンの能力を維持しているので... – Val

+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)); 
    });