I have a fixed menu, how to do anchoring (#internal links) get below the menu?

Asked

Viewed 2,044 times

2

I am working on a site that has a navbar and a menu (the height of the two summed gives 101px), that as you scroll up to them, they fixate on the top of the screen and stay floating.

I’m hoping that the anchors I set on the page are not overwritten by the menu when clicked by the user on the menu buttons.

For example, when the user clicks on "Main Dates" the anchor leads to the desired location, but as the menu floats it is above the title. Can be solved by changing the position of the page, but this also changes the height of the page.

I saw some resolution templates using Jquery, but all I tested didn’t work.

My website: https://sienpro.catalao.ufg.br/

What I want to do is like this example: http://jsfiddle.net/yjcRv/346/

I’m using this code:

<script src="http://code.jquery.com/jquery-1.7.1.js"></script>

<script type="text/javascript">

$('a[href*=#]').bind("click", function(e) {

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

    $('html,body').animate({ 'scrollTop': scrollToPosition }, 600, function(target){
        window.location.hash = target;
    });

    e.preventDefault();
});

</script>

Ah and the menu links are not defined simply as "#link", they are complete https://sienpro.catalao.ufg.br/#link, because if the user is on another page he will be redirected to the correct page and the anchor will take him to the set position.

  • Cara has a way of doing only with CSS and HTML, but it’s kind of a "gambiarra". You will have to make a "Hidden Anchor" that will prevent the title gets covered by the menu giving a space to the top of the page. If you want me to put it in the answer.

  • If you can! I think it would be one of the easiest ways to solve! I just want it to stay functional.

4 answers

3


I noticed some problems in the code:

first. When using the animate jQuery with anchors, do not use name="alvo"; use id="alvo". So change everything you have name="alvo" for id="alvo" (ex., name="datas" for id="datas"). Also change the tag of <a> for <div>, getting <div id="alvo"></div>.

2nd. This way to capture the click:

$('a[href*=#]').bind("click", function(e) {

In addition to missing quotes in #, try not to use .bind, because it has been discontinued since version 3 of jQuery. Instead, use .on().

Another thing, it looks like these <a> referenced are dynamic and jQuery is unable to identify them. To solve this, change the capture form to:

$(document).on("click", 'a[href*="#"]', function(e) {

3º. This code:

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

I realized that 101 is not the correct value. Use something around 200 because it needs to compensate that top above the menu. So it would be:

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

Then the code would look like this:

$(document).on("click", 'a[href*="#"]', function(e) {

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

    $('html,body').animate({ 'scrollTop': scrollToPosition }, 600, function(){
       window.location.hash = target;
    });

    e.preventDefault();
});

0

Lucas as I said in the comment and you asked for the example I will explain how with CSS and HTML you can solve this. It’s okay that this is not a very "classy" way, but it can solve in your case.

The technique is to create a 1px element and transparent color that will function as a hidden anchor, with the position:absolut you will take this element out of the page flow and it will not interfere with the other elements.

Follow a practical example for you to better understand

OBS: I left the comments in the code to facilitate

html {
    overflow-y: scroll;
    scroll-behavior: smooth;
} 
body {
    min-height: 2000px;
    padding-top: 70px;
}
div#header{
   position: fixed;
   top:0px;
   width:100%;
   height:80px;
   background: red;
   z-index: 999;
}

div#target{
   font-size:40px;
   border-top:1px solid red; 
   height: 80px;
}

/* Ancora Oculta - Classe do elemento que vai ser  */
#ancora1, #ancora2 {
    position: absolute;
    width: 1px;
    height: 1px;
    left: 0;
    margin-top: -100px; /* esse valor varia de acordo com a altura do seu Header, se ele tiver 200px de altura coloque aqui -220px por exemplo */
    background-color: transparent;
    z-index: -1;
}
<div id="header">
    <a href="#ancora1"># Ancora 1 #</a>
    <a href="#ancora2"># Ancora 2 #</a>
</div>

<div id="target" style="position: relative;">content!</div>
<div id="target">content!</div>
<div id="target" style="position: relative;">content!</div>
<div id="target">content!</div>
<!-- Elemento com o ID para fazer a Ancora 1 -->
<div id="ancora1"></div> 
<div id="target"># Ancora 1 #</div>
<div id="target">content!</div>
<div id="target">content!</div>
<!-- Elemento com o ID para fazer a Ancora 1 -->
<div id="ancora2"></div>
<div id="target"># Ancora 2 #</div>

As I said is not a very elegant technique, but can help you without Javascript

  • #anchor 1, #anchor 2 { position: Absolute; width: 1px; height: 1px; left: 0; margin-top: -100px; /* this value varies according to the height of your Header, if it is 200px high put here -220px for example */ background-color: Transparent; z-index: -1; } That part solved, thank you!

  • Lucas but it’s that part right there that’s the gold rss. She who does the magic. It is not very elegant, but resolves.

0

If the element . menu-bar and . menu_component are in the class "fix" just subtract their size (which you said is 101px).

$('html,body').animate({ 'scrollTop': (scrollToPosition - (101 + 33)) }, 600, function(target){
    window.location.hash = target;
})

Now if they are not in the "fix" class then in addition to subtracting the 10 from the menu size you have to take tbm the size of the header element(100) and the first_place element(33)

$('html,body').animate({ 'scrollTop': (scrollToPosition - (101 + 33 + 100 )) }, 600, function(target){
    window.location.hash = target;
})

In an opera summary, you have to calculate with the size of the header element and first_place

0

"I played" that same code on codepen changing the bind for on and the selector for ('#header > a') and it worked:

Edit: here was the link to a solution in codepen, but I was warned not to be able to post external links.

content of the link:

HTML:

<div id="header">
    Header: <a href="#target">Click me!</a>
</div>

   <div id="target">My target content!</div>

Javascript:

$('#header > a').on("click", function(e) {

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

$('html').animate({ 'scrollTop': scrollToPosition }, 600, function(target){
        window.location.hash = target;
    });

    e.preventDefault();
});
  • Put your code in the answer. Avoid external links

  • It works, but I want it to work as well when the user accesses the link from another page. So I want to disable the automatic "jump" for the hashtag, load the page and then slide to the hashtag. I tried to make it like this link but I couldn’t understand it. https://stackoverflow.com/questions/27096621/how-to-disable-anchor-jump-when-loading-a-page/29823834#29823834

  • In fact you can add the link, but the ideal is to add a relevant chunk of the link, as the page address may expire and the answer becomes "invalid".

  • For example when you access the direct link https://sienpro.catalao.ufg.br/#contact, it already jumps straight to where the anchor is, without going through Javascript and then the menu continues in front of the title. But if you click a button that is href="#contact" it performs the scroll correctly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.