2012-07-06 5 views
22

ich den folgenden Code verwenden zu blättern Punkte mit jQuery zu verankern:jQuery blättern zu verankern (minus festgelegte Menge an Pixeln)

$(document).ready(function() { 
    function filterPath(string) { 
    return string 
    .replace(/^\//,'') 
    .replace(/(index|default).[a-zA-Z]{3,4}$/,'') 
    .replace(/\/$/,''); 
    } 
    var locationPath = filterPath(location.pathname); 
    var scrollElem = scrollableElement('html', 'body'); 

    $('a[href*=#]').each(function() { 
    var thisPath = filterPath(this.pathname) || locationPath; 
    if ( locationPath == thisPath 
    && (location.hostname == this.hostname || !this.hostname) 
    && this.hash.replace(/#/,'')) { 
     var $target = $(this.hash), target = this.hash; 
     if (target) { 
     var targetOffset = $target.offset().top; 
     $(this).click(function(event) { 
      event.preventDefault(); 
      $(scrollElem).animate({scrollTop: targetOffset}, 400, function() { 
      location.hash = target; 
      }); 
     }); 
     } 
    } 
    }); 

    // use the first element that is "scrollable" 
    function scrollableElement(els) { 
    for (var i = 0, argLength = arguments.length; i <argLength; i++) { 
     var el = arguments[i], 
      $scrollElement = $(el); 
     if ($scrollElement.scrollTop()> 0) { 
     return el; 
     } else { 
     $scrollElement.scrollTop(1); 
     var isScrollable = $scrollElement.scrollTop()> 0; 
     $scrollElement.scrollTop(0); 
     if (isScrollable) { 
      return el; 
     } 
     } 
    } 
    return []; 
    } 

}); 

Gibt es trotzdem, um es zu diesem Anker zu machen zu bewegen, aber abzüglich ein festgelegter Betrag von Pixeln? (in meinem Fall möchte ich es -92px gehen)

Danke für jede Hilfe.

+0

Ähnlich http://stackoverflow.com/questions/832860/how-to-scroll-the-window-using-jquery-scrollto-function – robbrit

+0

Wie sind sie ähnlich ??Meine ist, über JQuery zu JEDEM Anker zu scrollen, was Sie verlinkt haben, möchte scrollen, wenn sie in der Nähe des oberen Randes der Seite sind. Der Code ist sehr unterschiedlich. – John

+0

Der einzige Unterschied besteht darin, zu welchem ​​Selektor Sie blättern möchten, und zum Offset. Sehen Sie sich die akzeptierte Antwort an und ersetzen Sie "# id" durch den gewünschten Selektor und ersetzen Sie "100" durch den von Ihnen gewünschten Offset. – robbrit

Antwort

23

Ich musste dieses Problem nur selbst lösen. Sie müssen Ihren Offset um die Anzahl der Pixel anpassen, die Sie scrollen möchten. In meinem Fall brauchte ich 50 Pixel höher auf der Seite. Also habe ich 50 von targetOffset subtrahiert.

Jetzt ist der Teil des Codes, der für Sie ein Wobbly wirft, location.hash - das sagt dem Browser, dass er seinen Ort auf einen bestimmten Punkt einstellen soll. In allen Fällen ist dies eine Zeichenfolge, die die ID enthält, zu der Sie gerade gescrollt haben. Also wäre es so etwas wie "# foo". Sie müssen dies beibehalten, also werden wir es verlassen.

Um jedoch zu verhindern, dass der Browser springt, wenn location.hash gesetzt ist (eine Standard-Browseraktion), müssen Sie lediglich die Standardaktion verhindern. Übergeben Sie also Ihr Ereignis 'e' durch die Vervollständigungsfunktion in der Animate-Funktion. Rufen Sie dann einfach e.preventDefault() auf. Sie müssen sicherstellen, dass der Browser tatsächlich ein Ereignis aufruft, sonst wird es einen Fehler geben. Also, ein Wenn-Test behebt das.

Fertig. Hier ist der überarbeitete Code Chunk:

if (target) { 
    var targetOffset = $target.offset().top - 50; 
    $(this).click(function(event) { 
     if(event != 'undefined') { 
      event.preventDefault();} 
     $(scrollElem).animate({scrollTop: targetOffset}, 400, function(e) { 
      e.preventDefault(); 
      location.hash = target; 
     }); 
    }); 
    } 
+0

Sorry, ich weiß, dass dies eine alte Frage ist, aber: der animierte Callback erhält keine Parameter (siehe http://api.jquery.com/animate/), so dass e.preventDefault() fehlschlägt. Hat sich das in den letzten 2 Jahren geändert? Gibt es eine aktuelle Möglichkeit, das Standardverhalten von location.hash = target zu verhindern? – Andreyu

+0

Andreyu, werfen Sie einen Blick auf Borgar Antwort in http://stackoverflow.com/questions/1489624/modifying-document-location-hash-without-page-scrolling – cfillol

15

Dies ist, was ich benutze:

function scrollToDiv(element){ 
    element = element.replace("link", ""); 
    $('html,body').unbind().animate({scrollTop: $(element).offset().top-50},'slow'); 
}; 

... wo 50 die Anzahl der Pixel zu addieren/subtrahieren.

+0

Vielen Dank! genau das, was ich brauchte! – krunos

1

Ich konnte Jonathan Savages Lösung nicht verwenden, da ich einen Ereignisrückruf nicht ohne Fehler in animate() übergeben konnte. Ich hatte dieses Problem heute und fand eine einfache Lösung:

 var $target = $(this.hash), target = this.hash; 
     if (target) { 
     var targetOffset = $target.offset().top - 92; 
     $(this).click(function(event) { 
      event.preventDefault(); 
      $(scrollElem).animate({scrollTop: targetOffset}, 400, function() { 
      location.hash = targetOffset; 
      }); 
     }); 

subtrahieren Ihre Pixel aus der Variablen targetOffset versetzt, dann zuweisen location.hash auf diese Variable. Stoppt das Springen der Seite beim Scrollen zum Ziel-Hash.

5

Lol)

<span class="anchor" id="section1"></span> 
 
<div class="section"></div> 
 

 
<span class="anchor" id="section2"></span> 
 
<div class="section"></div> 
 

 
<span class="anchor" id="section3"></span> 
 
<div class="section"></div> 
 

 
<style> 
 
.anchor{ 
 
    display: block; 
 
    height: 115px; /*same height as header*/ 
 
    margin-top: -115px; /*same height as header*/ 
 
    visibility: hidden; 
 
} 
 
</style>

+0

perfekt danke, und ohne jquery! – timhc22

+0

Das funktioniert gut, aber Sie müssen wissen, dass es Links, Schaltflächen oder andere interaktive Elemente, die Sie in den 115px über dem Anker haben, und Sie können nicht auf sie klicken können ... – phoenix

+0

perfekte CSS-Lösung, danke –

9

Dieser Code Arbeit für mich in jedem Link Anker in meiner Website Respekt "150px" height für fix Menü oben.

<!-- SMOOTH SCROLL --> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
<script> 
$(function() { 
    $('a[href*=#]:not([href=#])').click(function() { 
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { 
     var target = $(this.hash); 
     target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); 
     if (target.length) { 
     $('html,body').animate({ 
      scrollTop: target.offset().top-150 
     }, 1000); 
     return false; 
     } 
    } 
    }); 
}); 
</script> 
<!-- End of SMOOTH SCROLL --> 
0

Dies ist eine jQuery-Implementierung, die ich verwende, die auf Никита Андрейчук-Lösung basiert. Die Pixeleinstellungsvariable kann auf diese Weise dynamisch festgelegt werden, obwohl sie in diesem Beispiel fest codiert ist.

$('a').each(function() { 
    var pixels = 145; 
    var name = $(this).attr('name'); 
    if (typeof name != 'undefined') { 
     $(this).css({ 
      'display' : 'block', 
      'height'  : pixels + 'px', 
      'margin-top' : '-' + pixels + 'px', 
      'visibility' : 'hidden' 
     }); 
    } 
}); 
0

Hier ist was ich benutze. Stellen Sie den Versatz auf das ein, was Sie brauchen.

$('a[href^="#"]').click(function(e) { 
    e.preventDefault(); 
    $(window).stop(true).scrollTo(this.hash {duration:1000,interrupt:true,offset: -50}); 
});