javascript - Få ankerlenke til å gå noen piksler over der den er lenket til
Jeg er ikke sikker på den beste måten å spørre/søke etter dette spørsmålet på:
Når du klikker på en ankerlenke, tar den deg til den delen av siden med det lenkede området nå øverst på siden. Jeg vil at ankerlenken skal sende meg til den delen av siden, men jeg vil ha litt plass på toppen. Altså, jeg vil ikke at den sender meg til den lenkede delen med den øverst på siden, jeg vil ha omtrent 100 piksler med plass der.
Gir dette mening? Er dette mulig?
Redigert for å vise kode - det er bare en ankerlenke:
<a href="#anchor">Click me!</a>
<p id="anchor">I should be 100px below where I currently am!</p>
Svar #1
Her er svaret for 2020 på dette:
#anchor {
scroll-margin-top: 100px;
}
Fordi det er bredt støttet!
Svar #2
OPPDATERING: Ikke flere stemmer opp, takk. Selv om dette er det aksepterte svaret, er det bedre og mer moderne svaret dette fra user127091. Mitt svar her har blitt ganske utdatert (med mindre du virkelig vil bruke javascript).
window.addEventListener("hashchange", function () {
window.scrollTo(window.scrollX, window.scrollY - 100);
});
Dette vil tillate nettleseren å gjøre jobben med å hoppe til ankeret for oss, og deretter vil vi bruke den posisjonen til å offsete fra.
REDIGER 1:
Som @erb påpekte, fungerer dette bare hvis du er på siden mens hash-en blir endret. Å gå inn på siden med en #something allerede i URL-en fungerer ikke med koden ovenfor. Her er en annen versjon for å håndtere det:
// 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).
MERK: For å bruke jQuery, kan du bare erstatte window.addEventListener med $ (window).on i eksemplene. Takk @Neon.
REDIGER 2:
Som påpekt av noen, vil ovennevnte mislykkes hvis du klikker på samme ankerlink to eller flere ganger på rad fordi det ikke finnes noen hashchange-hendelse for å tvinge offset.
Denne løsningen er en veldig lett modifisert versjon av forslaget fra @Mave og bruker jQuery-selektorer for enkelhets skyld
// 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 for dette eksempelet er her
Svar #3
Ved å jobbe kun med CSS kan du legge til en polstring på det ankrede elementet (som i løsningen ovenfor). For å unngå unødvendig hvitt rom kan du legge til en negativ margin av samme høyde:
#anchor {
padding-top: 50px;
margin-top: -50px;
}
Jeg er ikke sikker på om dette er den beste løsningen i alle tilfeller, men det fungerer bra for meg.
Svar #4
En enda bedre løsning:
<p style="position:relative;">
<a name="anchor" style="position:absolute; top:-100px;"></a>
I should be 100px below where I currently am!
</p>
Plasser bare <a>-taggen med absolutt posisjonering inne i et relativt posisjonert objekt.
Fungerer når man går inn på siden eller gjennom en hashendring på siden.
Svar #5
Dette vil fungere uten jQuery og på lastingen av siden.
(function() {
if (document.location.hash) {
setTimeout(function() {
window.scrollTo(window.scrollX, window.scrollY - 100);
}, 10);
}
})();
Svar #6
Beste løsning
<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>
Svar #7
Denne rene CSS-løsningen fungerer for meg.
:target:before {
content:"";
display:block;
height:90px; /* fixed header height*/
margin:-90px 0 0; /* negative fixed header height */
}
jeg fant det her -> https://www.wikitechy.com/tutorials/javascript/offsetting-an-html-anchor-to-adjust-for-fixed-header
Her er en fiddle: https://jsfiddle.net/e8o2p3az/