Rozliczanie stałego nagłówka za pomocą programu animate.scrolltop i (target).offset ().top;

To powinno być dość podstawowe pytanie, ale rzuciłem na to większość mojego poranka i w tym momencie jestem bliski rzucenia ręcznika. Nie mam nawet trochę js foo -- ale znalazłem ładnie skomentowany fragment kodu, który mam nadzieję wykorzystać do animowania linków anchor to jest:

$(document).ready(function() {
$('a[href*=#]').bind('click', function(e) {
e.preventDefault(); //prevent the "normal" behaviour which would be a "hard" jump

var target = $(this).attr("href"); //Get the target

var scrollToPosition = $(target).offset().top;

// perform animated scrolling by getting top-position of target-element and set it     as scroll target
$('html, body').stop().animate({ scrollTop: scrollToPosition}, 600, function() {
     location.hash = target;  //attach the hash (#jumptarget) to the pageurl
});

return false;

 });
});

Próbuję sprawić, by wylądował 30px nad offsetem ().top -- próbowałem

$('html, body').stop().animate({ scrollTop: scrollToPosition -30}, 600,

Co prawie działa-trafia we właściwe miejsce, ale potem odbija się.

Ja też tried

scrollTop: $(target).offset().top - 20 },

Ja też próbowałem

scrollTop: $(hash).offset().top + $('#access').outerHeight()

Co niczego nie zmienia.

Wygląda na to, że odpowiedź może być tutaj: problem z przewijaniem strony jQuery ze stałym nagłówkiem ale po prostu nie mogę go zrozumieć.

Wiem, że to jest podobne do innych pytań -- ale przeszedłem przez to, co mogłem znaleźć i jestem na tyle analfabetą, że nie byłem w stanie skopiować/wkleić niczego, co rozwiązuje problem.

Byłbym niezmiernie wdzięczny na rozwiązanie.

Wielkie dzięki,]}

Martin

PS

Ten drugi fragment kodu, który znalazłem, działa, ale usuwa hashtag, co czyni go w większości bezużytecznym.

$(function(){
$('a[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) {
            var targetOffset = $target.offset().top;
            $('html,body').animate({scrollTop: targetOffset - 30}, 1000);
            return false;
        }
    }
  });
});
Author: Community, 2012-01-30

3 answers

Edytowano: Musisz tylko wykryć wysokość ustalonego nagłówka i odjąć ją od scrollToPosition, które robiłeś poprawnie. Problem polega na tym, że window.location.hash = "" + target; przeskakuje stronę na górę elementu o tym id. Więc jeśli animujesz tam tak, jak robiłeś, a następnie zmieniasz ten hash, to "odbije się" tak, jak opisałeś. Oto pierwszy sposób, w jaki możemy z tym walczyć:

// Get the height of the header
var headerHeight = $("div#header").height();

// Attach the click event
$('a[href*=#]').bind("click", function(e) {
    e.preventDefault();

    var target = $(this).attr("href"); //Get the target
    var scrollToPosition = $(target).offset().top - headerHeight;

    $('html').animate({ 'scrollTop': scrollToPosition }, 600, function(){
        window.location.hash = "" + target;
        // This hash change will jump the page to the top of the div with the same id
        // so we need to force the page to back to the end of the animation
        $('html').animate({ 'scrollTop': scrollToPosition }, 0);
    });

    $('body').append("called");
});

Oto Nowy jsfiddle dla tej pierwszej metody: http://jsfiddle.net/yjcRv/1/

DALSZA EDYCJA: Jeszcze lepszym sposobem kontrolowania zdarzeń hash change jest użycie wtyczki typu jQuery Address. Dzięki temu możesz wykorzystać swoje wydarzenia hashchange znacznie więcej. Oto przykładowe użycie:

// Get the height of the header
var headerHeight = $("div#header").height();

$.address.change(function(evt){
    var target = "#" + evt["pathNames"][0]; //Get the target from the event data

    // If there's been some content requested go to it…else go to the top
    if(evt["pathNames"][0]){
        var scrollToPosition = $(target).offset().top - headerHeight;
        $('html').animate({ 'scrollTop': scrollToPosition }, 600);
    }else{
        $('html').animate({ 'scrollTop': '0' }, 600);
    }

    return false;
});

// Attach the click event
$('a').bind("click", function(e) {
    // Change the location
    $.address.value($(this).attr("href"));

    return false;
});

Przykład na żywo tutaj: http://www.vdotgood.com/stack/user3444.html

Uwaga: nie musisz teraz dodawać hash do atrybutu links href. Oto link, który można kierować z selektor jQuery:

<!-- This is correct -->
<a href="/target" class="myclass">Target</a>

<!-- These are incorrect -->
<a href="/#/target" class="myclass">Target</a>

<a href="#/target" class="myclass">Target</a>

Aby skierować ten link, użyj selektora w stylu:

$("a.myclass").click(function(){
    $.address.value($(this).attr("href"));
    return false;
});

Adres JQuery w rzeczywistości szuka linków, które mają następujący atrybut:

<a href="/target" rel="address:/target">Target</a>

Atrybut rel zawiera address:, po którym następuje względny adres URL zdefiniowany przez Ciebie w tym przypadku /target. Jeśli tego użyjesz, adres jQuery wykryje łącze i automatycznie uruchomi zdarzenie zmiany skrótu.

 14
Author: Steve O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-31 10:58:23

Wiem, że to stare pytanie (trochę), ale napotkałem podobny problem ze stałą rozwijaną nawigacją na stronie internetowej. Uwaga jest to fragment kodu płynnego przewijania, ale można go łatwo zmienić automatycznie, zmieniając szybkość animacji.

JQuery:

$('body').on('click','a[href^="#"]',function(event){
    event.preventDefault();
    var target_offset = $(this.hash).offset() ? $(this.hash).offset().top : 0;
    //change this number to create the additional off set        
    var customoffset = 75
    $('html, body').animate({scrollTop:target_offset - customoffset}, 500);
});

Używam tego fragmentu kodu przez długi czas bez żadnych problemów. Jedyne, co mi się w tym nie podoba, to to, że złapie każdy # tag. Więc w plugin jak Flexslider plugin gdzie nawigacja używa # ' s I ręcznie usuń je z wtyczki.

 6
Author: GregT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 07:13:34

Poprawiłem oryginalny skrypt z http://www.paulund.co.uk/smooth-scroll-to-internal-links-with-jquery . działa cuda, ale nie można ustawić opóźnienia tak jak jest.

var headerHeight = $("header").height();


        $(document).ready(function(){
    $('a[href^="#"]').on('click',function (e) {
        e.preventDefault();

        var target = this.hash,
        $target = $(target);

        $('html, body').stop().animate({
            'scrollTop': $target.offset().top - headerHeight
        }, 1200, 'swing', function () {
            window.location.hash = target ;
        });
    });
});

Tak, jestem trochę spóźniony, ale ten problem właśnie przyszedł mi do głowy... Zdrowie!

 1
Author: Neurone00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 19:42:43