Сделайте ссылку привязки на несколько пикселей выше, где она связана с

Я не уверен, как лучше спросить/найти этот вопрос:

Когда вы нажимаете на ссылку привязки, вы попадаете в этот раздел страницы со связанной областью в ОЧЕНЬ ТОПЕ страницы. Я хотел бы, чтобы привязная ссылка отправила меня на эту часть страницы, но мне хотелось бы, чтобы пространство было наверху. Как и в, я не хочу, чтобы он отправил меня в связанную с ним часть в ОЧЕНЬ ВЕРХНИХ, мне хотелось бы около 100 пикселей пространства.

Это имеет смысл? Это возможно?

Отредактировано для отображения кода - это всего лишь тег привязки:

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

<p id="anchor">I should be 100px below where I currently am!</p>

Ответ 1

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

Это позволит браузеру выполнять работу по прыжкам на якорь для нас, а затем мы будем использовать эту позицию для смещения.

РЕДАКТИРОВАТЬ 1:

Как было указано в @erb, это работает, только если вы находитесь на странице, пока хеш изменен. Ввод страницы с #something уже в URL-адресе не работает с указанным выше кодом. Вот еще одна версия:

// 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).

Примечание: Чтобы использовать jQuery, вы можете просто заменить window.addEventListener на $(window).on в примерах. Спасибо @Neon.

ИЗМЕНИТЬ 2:

Как указано несколькими, приведенное выше не будет выполнено, если вы нажмете на одну и ту же привязку два или более раза подряд, потому что нет значения hashchange для принудительного смещения.

Это решение является очень слегка измененной версией предложения от @Mave и использует селектора jQuery для простоты

// 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 для этого примера здесь

Ответ 2

Работая только с css, вы можете добавить дополнение к закрепленному элементу (как в вышеприведенном решении) Чтобы избежать лишних пробелов, вы можете добавить отрицательный запас той же высоты:

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

Я не уверен, что это лучшее решение в любом случае, но оно отлично работает для меня.

Ответ 3

Еще лучшее решение:

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

Просто поместите тэг <a> с абсолютным позиционированием внутри относительно позиционированного объекта.

Работает при вводе страницы или изменении хэша внутри страницы.

Ответ 4

Лучшее решение

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

Ответ 5

Это будет работать без jQuery и загрузки страницы.

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

Ответ 6

Чтобы связать элемент, а затем "поместить" этот элемент на произвольное расстояние от верхней части страницы, используя чистый CSS, вам придется использовать padding-top, таким образом, элемент все еще находится наверху окна, но видимо, чтобы оно было расположено на некотором расстоянии от вершины порта просмотра, например:

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

Чтобы использовать простой подход к JavaScript:

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

window.addEventListener('hashchange', addMargin);

JS Fiddle demo.

Ответ 7

Если вы используете явные имена привязок, такие как

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

то в css вы можете просто установить

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

Это будет работать до тех пор, пока ваши метки привязки HREF также не будут указывать атрибут NAME

Ответ 8

Это должно работать:

    $(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;
    });
});

Просто измените .top-49 на то, что соответствует вашей якорной ссылке.

Ответ 9

Ответ Эрика велик, но вам действительно не нужен этот тайм-аут. Если вы используете jQuery, вы можете просто ждать загрузки страницы. Поэтому я предлагаю изменить код на:

// 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();
});

Это также избавляет нас от этого произвольного фактора.

Ответ 10

попробуйте этот код, он уже имеет плавную анимацию при нажатии на ссылку.

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

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

Ответ 11

Самое простое решение:

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>

Ответ 12

Вариант решения Томаса: селекторы CSS element> element могут быть полезны здесь:

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>

Щелчок по ссылке переместит позицию прокрутки на 100 пикселей выше, где бы ни находился элемент с классом paddedAnchor.

Поддерживается в браузерах, отличных от IE, и в IE начиная с версии 9. Для поддержки IE 7 и 8 необходимо объявить <!DOCTYPE>.

Ответ 13

Я просто нашел простое решение для себя. Имел край вершины 15px

HTML

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

CSS

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

Ответ 14

Я знаю, что это немного поздно, но я нашел что-то очень важное для ввода кода, если вы используете Bootstrap Scrollspy. (http://getbootstrap.com/javascript/#scrollspy)

Это заставляло меня гать часами.

Смещение для шпиона прокрутки ДОЛЖНО соответствовать параметру window.scrollY, иначе вы рискуете:

  • Получение странного эффекта мерцания при прокрутке
  • Вы увидите, что когда вы нажимаете на якоря, вы попадете в этот раздел, но шпион прокрутки предположит, что вы находитесь над ним.

 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);
});

Ответ 15

На основе решения @Eric Olson просто немного измените, чтобы включить элемент привязки, который я хочу специально

// 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);
});

Ответ 16

У меня просто такая же проблема. У меня есть положенная навигация, и я хочу, чтобы Angkor запускался под навигацией. Решение window.addEventListener... не работает для меня, потому что я установил для своей страницы scroll-behavior:smooth поэтому он установил смещение вместо прокрутки до angkor. setTimeout() работает, если времени достаточно для прокрутки до конца, но оно все еще выглядит не очень хорошо. поэтому я решил добавить положительный абсолютный div в ангкор, с height:[the height of the nav] и bottom:100%. в этом случае этот div заканчивался в верхней части элемента angkor и начинался с позиции, в которой вы должны прокрутить angkor. Теперь все, что я делаю, это устанавливаю ссылку Angkor на этот абсолютный div и готово :)

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>

Ответ 17

я столкнулся с подобной проблемой, и я решил, используя следующий код

$(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();
    });

Ответ 18

Использование только css и отсутствие проблем с закрытым и не кликабельным содержимым ранее (смысл этого в событиях указателя: нет):

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>

Ответ 19

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

<div style="margin-top: -100px; padding-top: 100px;" id="anchor"></div>
<p>I should be 100px below where I currently am!</p>