TransWikia.com

Скрыть блок в зависимости от скрола

Stack Overflow на русском Asked on November 25, 2021

На сайте имеется плавающая кнопка, при нажатии появляется форма, можно ли как-то сделать если пользователь проскролил страницу на 30% эта форма скрылась?

То есть ее в любом месте можно открыть и если прокрутить страницу форма сама скроется.

2 Answers

Вариант на jQuery

let hide = 30; // если позиция скролла >30% от всей страницы - то элемент будет скрыт
hide = ($(document).height() - $(window).height()) / 100 * hide;
let isHide = $(window).scrollTop() >= hide ? true : false; // "оптимизация" от лишних просчётов.

$(window).on({
  'scroll': function(){
    if($(this).scrollTop() >= hide && isHide === false) {
      isHide = true;
      $('.form').fadeOut(500);
    } else if($(this).scrollTop() < hide && isHide === true) {
      isHide = false;
      $('.form').fadeIn(500);
    }
  },
  'resize': function(){
    hide = ($(document).height() - $(window).height()) / 100 * hide;
  }
});
body {
  height: 1000px;
}

.form {
  display: block;
  width: 250px;
  height: 100px;
  background: blue;
  color: #fff;
  position: fixed;
  right: 0;
  bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="form">
  Ваша форма
</div>


Подумав предумал такой вариант, закрывается после того, как пользователь проскроллил расстояние >30% от высоты экрана.

let isHide = false,
    curS = [],
    winH = Math.round($(window).height() / 100 * 30);

$('.header__top span').on('click', function() {
  $('.header__bottom').slideToggle(100);
  curS[0] = $(window).scrollTop() - winH;
  curS[1] = $(window).scrollTop() + winH;
  isHide = true;
});

$(window).on({
  'scroll': function(){
    if(isHide === true && ($(window).scrollTop() >= curS[1] || $(window).scrollTop() <= curS[0])) {
      isHide = false;
      $('.header__bottom').slideUp(100);
    }
  },
  'resize': function(){
    winH = Math.round($(window).height() / 100 * 30);
  }
});
body {
  height: 2000px;
}

.header {
  position: fixed;
  top: 0;
  width: 400px;
  background: blue;
  color: #fff;
}

.header__bottom {
  display: none;
}

.wrapper {
  height: 10000px;
  width: 400px;
  border: 1px solid
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="wrapper">
  <div class="header">
    <div class="header__top">
      <span>Открыть поиск</span>
    </div>
    <div class="header__bottom">
      <form action="/"><input type=""><button>искать</button></form>
    </div>
  </div>
</div>

Answered by De.Minov on November 25, 2021

Для того что бы это реализовать нам достаточно знать высоту контейнера и то насколько далеко он проскроллен вниз.

Поставим прослушку по событию scroll, что бы отслеживать изменения и добавим условие по которому мы будем скрывать нужный нам блок.

Теперь если пользователь проскроллит контейнер более чем на 30%, а требуемый блок будет находиться в открытом положении открыт, то мы его закроем:

$(".header__top span").on("click", function() {
  $(".header__bottom").slideToggle(100)
})

$(window).on("scroll", function() {
  const body = $("body")[0]
  const $header_bottom = $(".header__bottom")  
  const height = body.clientHeight
  const top = body.scrollTop
  
  if (top > Math.round(height * (1 / 100) * 30)) {
    if ($header_bottom.css("display") === "block") {
      $header_bottom.hide()
    }
  }
})
.header {
  position: fixed;
  top: 0;
  width: 400px;
  background: blue;
  color: #fff;
}

.header__top span {
  cursor: pointer;
}

.header__bottom {
  display: none;
}

.wrapper {
  height: 2000px;
  width: 400px;
  border: 1px solid
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="header">
    <div class="header__top">
      <span>Открыть поиск</span>
    </div>
    <div class="header__bottom">
      <form action="/"><input type=""><button>искать</button></form>
    </div>
  </div>
</div>

Изначальный вариант на JS:

window.addEventListener("scroll", () => {
  const height = document.body.clientHeight
  const top = document.body.scrollTop
  const header_bottom = document.querySelector(".header__bottom")
  if (top > Math.round(height * (1 / 100) * 30)) {
    if (header_bottom.style.display === "block") {
      header_bottom.style.display = "none"
    }
  }
})

Имейте ввиду, что поскольку постоянные реакция на событие "scroll" очень затратны для браузеров Вам нужно будет использовать debounce что бы не допустить просадки производительности Вашей(го) страницы(приложения).

Answered by Vasily on November 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP