2009-07-11 7 views
1

J'ai créé une fonction qui fait défiler un élément enfant donné dans la vue de son parent. Il se présente comme suit:Avis jQuery: Comment améliorer cette fonction pour faire défiler des éléments?

function keepScrolledOver(elem) 
{ 
    frame = elem.parent(); 

    var scrollPos = frame.scrollTop(); 
    var offset = elem.attr("offsetTop"); 

    // If the element is scrolled too high... 
    if(offset < scrollPos) 
    { 
     frame.scrollTop(offset); 
     // frame.attr("scrollTop", offset); 
    } 

    // If the element is scrolled too low... 
    else 
    { 
     var frameHeight = frame.height(); 
     var offsetBottom = offset + elem.height(); 
     var scrollBottom = scrollPos + frameHeight; 


     if(offsetBottom > scrollBottom) 
     { 
      // frame.attr("scrollTop", offsetBottom); 
      if(frameHeight < offsetBottom) 
       frame.scrollTop(offsetBottom - frameHeight); 
       // frame.attr("scrollTop", offsetBottom - frameHeight); 
     } 
    } 
} 

Jusqu'à présent, pour mon application web Firefox (Firefox est tout ce que je l'ai testé sur ce jour, je veux dire), cela fonctionne très bien. Le seul problème est que pour les éléments défilant trop bas, il a toujours tendance à défiler juste un peu au-delà de l'élément cible plutôt que jusqu'à la fin. Je ne suis pas sûr si le rembourrage d'élément a quelque chose à faire avec ou si mes maths juste sucent.

Quelqu'un at-il des idées brillantes sur la façon d'améliorer cela?

Répondre

1

La section de code qui se déclenche si l'élément est trop élevé fonctionne correctement, en supposant que l'élément frame et ses éléments enfants sont positionnés de manière relative. Sinon, il utilise le décalage absolu et cela ne fonctionne pas. En ce qui concerne la section qui se déclenche si l'élément est trop bas, je suppose que lorsque vous dites "il a toujours tendance à faire défiler juste un petit peu devant l'élément cible plutôt que jusqu'à sa fin", vous faites référence à fait que l'élément est coupé si le cadre est plus petit que son décalage. Essayez ce qui suit:

// If the frame is less than or equal to the element's height 
if(frameHeight <= elem.attr('height')){ 
    //Scroll to it's offsetBottom - the total frameHeight, so that the full element will be displayed 
    frame.scrollTop(offsetBottom - frameHeight); 
}else { 
    //Else, the element's height is less than the frame, so the entire element will be displayed if we just scroll to the element's offsetBottom. 
    frame.scrollTop(offsetBottom); 
} 

J'ai créé une page de démonstration HTML comme suit et n'ai rencontré aucun autre problème. Jouez avec les hauteurs des éléments et voyez si vous pouvez l'obtenir pour casser. J'ai utilisé Firefox 3.5 et tout était cool.

<button id="buttonTest1">Slide to Test1</button> <button id="buttonTest2">Slide to Test2</button> 
<div style="position:relative;width:100%;height:620px;overflow:scroll;"> 
    <div style="position:relative;height:50px;"></div> 
    <div id="childSlide1" style="width:50px;height:50px;position:relative;">Test</div> 
    <div id="childSlide2" style="width:50px;height:50px;position:relative;top:850px;">Test2</div> 
</div> 


$(document).ready(function(){ 
    function keepScrolledOver(elem){ 
     var frame = elem.parent(); 

     var scrollPos = frame.scrollTop(); 
     var offset = elem.attr("offsetTop"); 
     alert ('scrollPos: '+scrollPos+' offset: '+offset); 
     //var jQoffset = elem.offset(); 
     //alert ('jQoffset: '+jQoffset.top+' '+jQoffset.left); 
     // If the element is scrolled too high... 
     if(offset < scrollPos) 
     { 
       alert ('scrollPos '+scrollPos+' is bigger than offset '+offset); 
       frame.scrollTop(offset); 
       // frame.attr("scrollTop", offset); 
     } 

     // If the element is scrolled too low... 
     else 
     { 
       var frameHeight = frame.height(); 
       var offsetBottom = offset + elem.height(); 
       var scrollBottom = scrollPos + frameHeight; 
       alert('frameHeight: '+frameHeight+' offsetBottom: '+offsetBottom+' scrollBottom: '+scrollBottom); 


       if(offsetBottom > scrollBottom) 
       { 
         // frame.attr("scrollTop", offsetBottom); 
         if(frameHeight <= elem.attr('height')) 
         { 
          frame.scrollTop(offsetBottom - frameHeight); 
          // frame.attr("scrollTop", offsetBottom - frameHeight); 
         }else { 
          frame.scrollTop(offsetBottom); 
         } 
       } 
     } 
    } 

    $('#buttonTest1').click(function(){ 
     var scrollElement = $('#childSlide1'); 
     keepScrolledOver(scrollElement); 
    }); 

    $('#buttonTest2').click(function(){ 
     var scrollElement = $('#childSlide2'); 
     keepScrolledOver(scrollElement); 
    });  
}); 
Questions connexes