Автор: Stasyuk Eugene 88 Метки: 24.03.2024

В последнее время я уже давно не встречал сайты, которые не имеют фиксированный header. Такой подход уже стал обычной практикой. Как минимум очень удобно когда навигация по сайту всегда находится под рукой. Но есть один момент, который может доставить дискомфорт при таком подходе — это якорные ссылки. Обычно при клике на такую ссылку, секция с указанным Id оказывается вверху окна браузера. И если header у нас имеет position: fixed, то ,следовательно, он будет перекрывать часть контента секции:

Есть много способов нивелировать данную проблему. В этой статье я предложу относительно универсальный способ. В нем мы будем также учитывать якорные ссылки, которые могут находится на разных страницах.

Готовый пример: https://codepen.io/jecosjmecos/pen/jORmQeg

Немного подробней остановимся на js коде:

document.addEventListener('DOMContentLoaded', function() {
    // Moving to anchor on page load
    scrollToAnchor();

    // Move to anchor when clicking on anchored links
    const headerLinks = document.querySelectorAll('a[href*="#"]');
  
    headerLinks.forEach(function(link) {
        link.addEventListener('click', function(event) {
          if(event.target.pathname === window.location.pathname){
            event.preventDefault();

            let hash = this.getAttribute('href').split('#')[1];

            scrollToAnchor('#' + hash);
          }
        });
    });
});

function scrollToAnchor(hash = window.location.hash) {
  if(hash.length > 1){
    let headerHeight = document.querySelector('header').offsetHeight,
        targetElement = document.querySelector(hash);

    if(targetElement) {
      var targetOffset = targetElement.offsetTop - headerHeight;
      
      window.scrollTo({
        top: targetOffset,
        behavior: 'smooth'
      });
    }
  }
}

Здесь мы имеем функцию scrollToAnchor. В качестве аргумента мы помещаем в нее id секции, которую нам необходимо будет показать в окне браузера. По умолчанию мы будем брать этот id из url текущей страницы (window.location.hash).

function scrollToAnchor(hash = window.location.hash) {
  if(hash.length > 1){
    let headerHeight = document.querySelector('header').offsetHeight,
        targetElement = document.querySelector(hash);

    if(targetElement) {
      var targetOffset = targetElement.offsetTop - headerHeight;
      
      window.scrollTo({
        top: targetOffset,
        behavior: 'smooth'
      });
    }
  }

В этой функции определяем высоту нашего header и проверяем наличие элемента с нужным id. Если такой присутствует, мы определяем координаты секции с учетом высоты header и плавно скролим к ней.

Вызывать функцию мы будем два раза. Один раз при загрузке страницы:

// Moving to anchor on page load
    scrollToAnchor();

Второй раз при клике на ссылку в меню шапки:

// Move to anchor when clicking on anchored links
    const headerLinks = document.querySelectorAll('a[href*="#"]');
  
    headerLinks.forEach(function(link) {
        link.addEventListener('click', function(event) {
          if(event.target.pathname === window.location.pathname){
            event.preventDefault();

            let hash = this.getAttribute('href').split('#')[1];

            scrollToAnchor('#' + hash);
          }
        });
    });

Другие статьи

Покажи свою работу presentation

Покажи свою работу

Покажи свою работу

Прочитал на днях книгу Остина Клеона «Покажи свою работу». Впечатление оставила очень хорошее. Благодаря ей я немного поменял взгляды на свою работу и на сам процесс в целом.  Чем же она меня так впечатлила?  Посыл этой книги довольно прост: покажи свою работу, в том числе и процесс ее создания. Время, когда зрителей интересовал только результат […]

DOMSubtreeModified — событие при изменении элемента action

DOMSubtreeModified — событие при изменении элемента

DOMSubtreeModified — событие при изменении элемента

Краткая предыстория Был у меня в работе сайт, в котором формы были настроены на плагине Contact Form 7. Сами же эти формы были интегрированы с Mailchimp. Задача состояла в следующем: после того, как пользователь заполнит и отправит определенную форму, сообщение должно попадать в сервис с определенным тегом (теги Mailchimp — это самый простой способ организовать […]