it-swarm.com.de

Verankern Sie den Anker-Link einige Pixel oberhalb, wo er verlinkt ist

Ich bin nicht sicher, wie man diese Frage am besten stellt/sucht:

Wenn Sie auf einen Anker-Link klicken, gelangen Sie zu dem Abschnitt der Seite mit dem verknüpften Bereich, der sich jetzt ganz oben auf der Seite befindet. Ich möchte, dass der Anker-Link mich zu diesem Teil der Seite schickt, aber ich möchte oben etwas Platz. Wie in, möchte ich nicht, dass es mich mit dem SEHR TOP an den verlinkten Teil sendet, ich möchte 100 oder so Pixel Pixel dort.

Macht das Sinn? Ist das möglich? 

Bearbeitet, um Code anzuzeigen - es ist nur ein Anker-Tag:

<a href="#anchor">Click me!</a>

<p id="anchor">I should be 100px below where I currently am!</p>
90
damon
window.addEventListener("hashchange", function () {
    window.scrollTo(window.scrollX, window.scrollY - 100);
});

Dadurch kann der Browser die Arbeit erledigen, indem wir zum Anker springen, und wir werden diese Position zum Versetzen verwenden.

EDIT 1:

Wie von @erb ausgeführt, funktioniert dies nur, wenn Sie sich auf der Seite befinden, während der Hash geändert wird. Die Eingabe der Seite mit einem #something bereits in der URL funktioniert nicht mit dem obigen Code. Hier ist eine andere Version, um das zu handhaben:

// The function actually applying the offset
function offsetAnchor() {
    if(location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}

// This will capture hash changes while on the page
window.addEventListener("hashchange", offsetAnchor);

// This is here so that when you enter the page with a hash,
// it can provide the offset in that case too. Having a timeout
// seems necessary to allow the browser to jump to the anchor first.
window.setTimeout(offsetAnchor, 1); // The delay of 1 is arbitrary and may not always work right (although it did in my testing).

HINWEIS: Um jQuery zu verwenden, können Sie in den Beispielen einfach window.addEventListener durch $(window).on ersetzen. Vielen Dank @Neon.

EDIT 2:

Wie von einigen wenigen aufgezeigt, schlägt das Obige fehl, wenn Sie auf denselben Anker-Link zwei oder mehrmals hintereinander klicken, da kein hashchange-Ereignis vorhanden ist, das den Versatz erzwingt.

Diese Lösung ist eine leicht modifizierte Version des Vorschlags von @Mave und verwendet zur Vereinfachung jQuery-Selektoren

// The function actually applying the offset
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 100);
  }
}

// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
    offsetAnchor();
  }, 0);
});

// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);

JSFiddle für dieses Beispiel ist hier

113
Eric Olson

Wenn Sie nur mit css arbeiten, können Sie dem verankerten Element (wie in einer Lösung oben) eine Auffüllung hinzufügen Um unnötigen Leerraum zu vermeiden, können Sie einen negativen Rand derselben Höhe hinzufügen:

#anchor {
    padding-top: 50px;
    margin-top: -50px;
}

Ich bin mir nicht sicher, ob dies auf jeden Fall die beste Lösung ist, aber es funktioniert gut für mich. 

69
user3364768

Noch bessere Lösung:

<p style="position:relative;">
    <a name="anchor" style="position:absolute; top:-100px;"></a>
    I should be 100px below where I currently am!
</p>

Positionieren Sie einfach das <a>-Tag mit der absoluten Positionierung innerhalb eines relativ positionierten Objekts.

Funktioniert beim Aufrufen der Seite oder durch einen Hashwechsel innerhalb der Seite.

49
Thomas

Beste Lösung

<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>

Dies funktioniert ohne jQuery und beim Laden der Seite.

(function() {
    if (document.location.hash) {
        setTimeout(function() {
            window.scrollTo(window.scrollX, window.scrollY - 100);
        }, 10);
    }
})();
7
M K

Um mit einem Element eine Verknüpfung herzustellen und dieses Element mit reinem CSS in beliebiger Entfernung vom oberen Rand der Seite zu positionieren, müssen Sie padding-top verwenden. Auf diese Weise befindet sich das Element immer noch am oberen Rand des Fensters es scheint sichtbar sichtbar in einiger Entfernung von der Oberseite des View-Ports zu liegen, zum Beispiel:

<a href="#link1">Link one</a>
<a href="#link2">Link two</a>

<div id="link1">
    The first.
</div>

<div id="link2">
    The second.
</div>

CSS:

div {
    /* just to force height, and window-scrolling to get to the elements.
       Irrelevant to the demo, really */
    margin-top: 1000px;
    height: 1000px;
}

#link2 {
    /* places the contents of the element 100px from the top of the view-port */
    padding-top: 100px;
}

JS Fiddle Demo .

So verwenden Sie einen einfachen JavaScript-Ansatz:

function addMargin() {
    window.scrollTo(0, window.pageYOffset - 100);
}

window.addEventListener('hashchange', addMargin);

JS Fiddle Demo .

4
David Thomas

Erics Antwort ist großartig, aber Sie brauchen diese Auszeit wirklich nicht. Wenn Sie jQuery verwenden, können Sie einfach warten, bis die Seite geladen ist. Ich würde also vorschlagen, den Code folgendermaßen zu ändern:

// The function actually applying the offset
function offsetAnchor() {
    if (location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}

// This will capture hash changes while on the page
$(window).on("hashchange", function () {
    offsetAnchor();
});

// Let the page finish loading.
$(document).ready(function() {
    offsetAnchor();
});

Dadurch werden wir auch diesen willkürlichen Faktor los.

3
rppc

Das sollte funktionieren:

    $(document).ready(function () {
    $('a').on('click', function (e) {
        // e.preventDefault();

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

       $('html, body').stop().animate({
        'scrollTop': $target.offset().top-49
    }, 900, 'swing', function () {
    });

        console.log(window.location);

        return false;
    });
});

Ändern Sie einfach das .top-49 so, wie es zu Ihrem Ankerlink passt.

3
dMehta

Wenn Sie explizite Ankernamen verwenden, z.

<a name="sectionLink"></a>
<h1>Section<h1>

dann in css kannst du einfach einstellen

A[name] {
    padding-top:100px;
}

Dies funktioniert, solange Ihre HREF-Ankertags nicht auch ein NAME-Attribut angeben

3
Mespr

versuchen Sie diesen Code, es hat bereits eine glatte Animation, wenn Sie auf den Link klicken.

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

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top - 100
    }, 500);
});
2
Maricar Onggon

Ich habe gerade eine einfache Lösung für mich gefunden ... Hatte einen Vorsprung von 15px

HTML

<h2 id="Anchor">Anchor</h2>

CSS

h2{margin-top:-60px; padding-top:75px;}
1
Gero

Die einfachste Lösung:

CSS

#link {
    top:-120px; /* -(some pixels above) */
    position:relative;
    z-index:5;
}

HTML

<body>
    <a href="#link">Link</a>
    <div>
        <div id="link"></div> /*this div should placed inside a target div in the page*/
        text
        text
        text
    <div>
</body>
1
Edalat Mojaveri

Eine Variante der Lösung von Thomas: CSS Element> Element Selektoren kann hier hilfreich sein:

CSS

.paddedAnchor{
  position: relative;
}
.paddedAnchor > a{
  position: absolute;
  top: -100px;
}

HTML

<a href="#myAnchor">Click Me!</a>

<span class="paddedAnchor"><a name="myAnchor"></a></span>

Ein Klick auf den Link verschiebt die Bildlaufposition auf 100px darüber, wo sich das Element mit der Klasse paddedAnchor befindet.

Wird in Nicht-IE-Browsern und in IE ab Version 9 unterstützt. Zur Unterstützung von IE 7 und 8 muss ein <!DOCTYPE> angegeben werden.

0
HondaGuy

Ich habe nur das gleiche Problem. Ich habe ein Navi pixed und ich möchte, dass der Angkor unter dem Nav startet. Die Lösung von window.addEventListener... funktioniert nicht für mich, weil ich meine Seite auf scroll-behavior:smooth gesetzt habe, also den Offset stattdessen zum Angkor scrolle. Die setTimeout() funktioniert, wenn die Zeit ausreichend ist, um bis zum Ende zu blättern, aber immer noch nicht gut aussieht. Meine Lösung bestand also darin, im Angkor ein posiertes absolutes div mit height:[the height of the nav] und bottom:100% hinzuzufügen. In diesem Fall endete dieses div in der Spitze des Angkor-Elements und beginnt an der Position, an der Sie den Angkor verschieben möchten. Jetzt ist alles was ich mache, den Angkor-Link zu diesem absoluten Div und der Welt gesetzt :)

html,body{
    margin:0;
    padding:0;
    scroll-behavior:smooth;
}

nav {
    height:30px;
    width:100%;
    font-size:20pt;
    text-align:center;
    color:white;
    background-color:black;
    position:relative;
}

#my_nav{
    position:fixed;
    z-index:3;
}
#fixer_nav{
    position:static;
}

#angkor{
    position:absolute;
    bottom:100%;
    height:30px;
}
<nav id="my_nav"><a href="#angkor">fixed position nav<a/></nav>
<nav id="fixer_nav"></nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
</p>

<nav><div id="angkor"></div>The angkor</nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

</p>

0

Ich weiß, dass dies etwas spät ist, aber ich habe etwas sehr Wichtiges gefunden, um Ihren Code einzufügen, wenn Sie Bootstraps Scrollspy verwenden. ( http://getbootstrap.com/javascript/#scrollspy )

Das hat mich stundenlang verrückt gemacht.

Der Offset für den Scroll-Spion MUSS mit dem Fenster.scrollY übereinstimmen, sonst besteht die Gefahr, dass

  1. Beim Scrollen kommt es zu einem seltsamen Flimmern
  2. Wenn Sie auf Anker klicken, landen Sie in diesem Bereich, aber der Rollenspion wird davon ausgehen, dass Sie sich darüber befinden. 

 var body = $('body');
    body.scrollspy({
        'target': '#nav',
        'offset': 100 //this must match the window.scrollY below or you'll have a bad time mmkay
});

$(window).on("hashchange", function () {
        window.scrollTo(window.scrollX, window.scrollY - 100);
});

0
beefsupreme

Basierend auf @Eric Olson Lösung modifizieren Sie einfach ein wenig, um das Ankerelement aufzunehmen, das ich speziell machen möchte

// Function that actually set offset
function offsetAnchor(e) {
    // location.hash.length different to 0 to ignore empty anchor (domain.me/page#)
    if (location.hash.length !== 0) {
        // Get the Y position of the element you want to go and place an offset
        window.scrollTo(0, $(e.target.hash).position().top - 150);
    }
}

// Catch the event with a time out to perform the offset function properly
$(document).on('click', 'a[href^="#"]', function (e) {
    window.setTimeout(function () {
        // Send event to get the target id later
        offsetAnchor(e);
    }, 10);
});
0
Carlos A. Ortiz

Verwenden Sie nur CSS und haben Sie keine Probleme mit verdeckten und nicht anklickbaren Inhalten (der springende Punkt sind die Zeigerereignisse: keine):

CSS

.anchored::before {
    content: '';
    display: block;
    position: relative;
    width: 0;
    height: 100px;
    margin-top: -100px;
}

HTML

<a href="#anchor">Click me!</a>
<div style="pointer-events:none;">
<p id="anchor" class="anchored">I should be 100px below where I currently am!</p>
</div>
0
dantefff

ich war mit einem ähnlichen Problem konfrontiert und konnte den folgenden Code verwenden 

$(document).on('click', 'a.page-scroll', function(event) {
        var $anchor = $(this);
        var desiredHeight = $(window).height() - 577;
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top - desiredHeight
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
0
Umair Mehmood