• CSS
  • JavaScript

Как сделать на сайте скрытие кнопки при скролле?

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

За основу взял сss-код из примера многоуважаемого Александра и скрестил все это дело с js-кодом из инета. На удивление все заработало неплохо =). Но есть пара моментов, которые я не знаю как реализовать, поэтому и прошу помочь.

И так: есть кнопка наверх на JavaScript. Сейчас она появляется при превышении определенного значения pageYOffset, и убирается так же, при возврате в нужную зону.

А мне необходимо реализовать следующее: Кнопка появляется как обычно при превышении установленного значения pageYOffset, а затем, через несколько секунд исчезает при отсутствии скролла. После этого заново появляется при любом скроле, если она находится в пределах значений pageYOffset, в которых она должна быть.

Второй вариант отличается от первого только тем, что кнопка, после того, как скрылась, должна появляться только при скролле, если значение на которое он произошёл больше определенного количества пикселей.

Вот ссылка на codepen: https://codepen.io/man129/pen/NWdBNrd

Подскажите кто знает, как можно реализовать это. Да и вообще адекватно ли эта функция реализована. Может возможно её более просто ее реализовать.

Благодарю!

Ответы: 8

Аноним
Аноним
Привет!
Скролл к началу страницы на чистом JavaScript проще реализовать через scrollTo. Так кода будет меньше:
window.scrollTo({
  top: 0,
  behavior: "smooth"
});
Для того чтобы кнопка «Вверх» исчезала через 3 секунды после скролла можно написать следующий код:
document.addEventListener("DOMContentLoaded", () => {
  let toTopBtn = document.querySelector(".to-up");
  let pageYOffset = 0;
  let timeout;
  window.onscroll = function () {
    if (timeout) {
      window.clearTimeout(timeout);
    }
    if (window.pageYOffset > 580) {
      toTopBtn.style.display = "block";
    } else {
      toTopBtn.style.display = "none";
    }
    pageYOffset = window.pageYOffset;
    timeout = window.setTimeout(function(){
      if (window.pageYOffset === pageYOffset) {
        toTopBtn.style.display = "none";
      }
    }, 3000);
  }
  // плавный скролл наверх
  toTopBtn.addEventListener("click", function () {
    window.scrollTo({
      top: 0,
      behavior: "smooth"
    });
  });
});
Cсылка на codepen: codepen.io/itchief/pen/NWdBRqZ
Аноним
Аноним
Александр в очередной раз огромное спасибо за решение! Работает js просто изумительно!) Осталось разобраться с валидатором который постоянно на меня ругается… Если будет время не могли бы вы мельком посмотреть что нужно исправить или добавить и как валидней прописать эту кнопку? Сама кнопка меня по оформлению полностью устраивет и минимальна по коду, но валидатора это не волнует…

HTML
<div class="to-up">
 <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 17V4M3 10l7-7 7 7'/%3E%3C/g%3E%3C/svg%3E" alt="Стрелка вверх">
 </div> 
CSS — я так понимаю учитывая js код можно вообще не указывать display: none и убрать этот пункт из css?
.to-up {
  position: fixed; /* фиксированная позиция */
  color: #fff; /* цвет текста */
  background-color: #3aa111; /* цвет заднего фона */
  right:  5px; /* расстояние от правого края */
  bottom: 80px; /* расстояние от нижнего края */
  padding: 13px 13px; /* отступы до содержимого блока */
  border-radius: 100%; 
  cursor: pointer; /* форма курсора */
  display: none; /* не отображать элемент */
  text-align: center; /*выравнивание содержимого элемента по центру */
}
div.to-up:hover {
  background-color: orange; /* цвет заднего фона при наведении */
}

@media screen and (min-width: 480px) {
  .to-up {
  right: 20px; /* расстояние от правого края */
  }
}
Codepen -> codepen.io/man129/pen/NWdBNrd

Огромное спасибо! ;)
Аноним
Аноним
Пожалуйста!
В HTML верстку можно сделать просто такой (саму стрелку создать через псевдоэлемент, например, ::before):
<div class="to-up"></div>
CSS:
.to-up {
  position: fixed; /* фиксированная позиция */
  color: #fff; /* цвет текста */
  background-color: #3aa111; /* цвет заднего фона */
  right: 20px; /* расстояние от правого края */
  bottom: 40px; /* расстояние от нижнего края */
  border-radius: 100%; 
  cursor: pointer; /* форма курсора */
  display: none; /* не отображать элемент */
  width: 40px;
  height: 40px;
}
.to-up::before {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  left: 10px;
  top: 10px;
  background: transparent no-repeat center center;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 17V4M3 10l7-7 7 7'/%3E%3C/g%3E%3C/svg%3E");
}
div.to-up:hover {
  background-color: orange; /* цвет заднего фона при наведении */
}
Codepen: codepen.io/itchief/pen/NWdBRqZ
Аноним
Аноним
Александр, вы гений и спаситель! Огромное человеческое Спасибо!)
Аноним
Аноним
Здравствуйте! Решил воспользоваться вашим методом создания кнопки «вверх». Скопировал ваш код из примера выше все работает как надо. Но если зайти в ваш codepen, там есть часть javascript кода которого нет в примере. И я не могу разобраться за что он отвечает. Сама кнопка работает как с этим кодом так и без него. Объясните пожалуйста за что все таки он отвечает. Я новичок в javascript, можно сказать только знакомлюсь с этим языком и практически ни чего не понимаю)
Вот эта часть непонятного для меня кода которую вы указали в codepen:

document.addEventListener("DOMContentLoaded", function() {
  function hasTouchDevice() {
    return !!('ontouchstart' in window || navigator.maxTouchPoints);
  }
  if (!hasTouchDevice()) {
    const toUp = document.querySelector('.to-up');
    toUp.onmouseenter = function(){
      this.classList.add('hover');
    }
    toUp.onmouseleave = function() {
      this.classList.remove('hover');
    }
  }
});
А вот сам код из примера и тот который я взял за пример:
HTML
<div class="to-up"></div>
CSS

.to-up {
  position: fixed; /* фиксированная позиция */
  color: #fff; /* цвет текста */
  background-color: #3aa111; /* цвет заднего фона */
  left: 10px; /* расстояние от правого края */
  bottom: 53px; /* расстояние от нижнего края */
  border-radius: 100%; 
  cursor: pointer; /* форма курсора */
  display: none; /* не отображать элемент */
  width: 44px;
  height: 44px;
}
.to-up::before {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  left: 12px;
  top: 12px;
  background: transparent no-repeat center center;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 17V4M3 10l7-7 7 7'/%3E%3C/g%3E%3C/svg%3E");
}
.to-up:hover {
  background-color: #61b340; /* цвет заднего фона при наведении */
}
JS

document.addEventListener("DOMContentLoaded", () => {
  let toTopBtn = document.querySelector(".to-up");
  let pageYOffset = 0;
  let timeout;
  window.onscroll = function () {
    if (timeout) {
      window.clearTimeout(timeout);
    }
    if (window.pageYOffset > 900) {
      toTopBtn.style.display = "block";
    } else {
      toTopBtn.style.display = "none";
    }
    pageYOffset = window.pageYOffset;
    timeout = window.setTimeout(function(){
      if (window.pageYOffset === pageYOffset) {
        toTopBtn.style.display = "none";
      }
    }, 3000);
  }
  // плавный скролл наверх
  toTopBtn.addEventListener("click", function () {
    window.scrollTo({
      top: 0,
      behavior: "smooth"
    });
  });
});
Повторюсь сама кнопка работает что с непонятным мне кодом, что без него. Помогите пожалуйста разобраться за что отвечает этот непонятный мне код. Спасибо!
Аноним
Аноним
Здравствуйте! Функция hasTouchDevice проверяет имеет ли это устройство тач-экран. Если не имеет, то при вхождения курсора в .to-up добавляет ему класс hover, при покидании удаляет его. Если этот функционал нужен, то добавьте этот код.
Аноним
Аноним
Александр, здравствуйте! Теперь разобрался. Спасибо вам!
Аноним
Аноним
Видимо я еще слегка погорячился и все таки в консоле код выдает след.ошибки:
1) Uncaught TypeError: Cannot read property 'addEventListener' of null
at HTMLDocument.2) Uncaught TypeError: Cannot read property 'style' of null
at window.onscroll