Изменение фонового изображения при прокрутке

1

Я пытаюсь изменить фоновое изображение элемента после прокрутки определенной позиции. Вот фрагмент моего кода:

<body>
 <script>
  window.onscroll = function() {scrollBG()};

  function scrollBG() {
   if (document.body.scrollTop > document.getElementById("one").getBoundingClientRect().top ||
       document.documentElement.scrollTop > document.getElementById("one").getBoundingClientRect().top) {
     document.getElementById("outer").style.backgroundImage = "url('imgs/pic1.jng')";
   } else {
     document.getElementById("outer").style.backgroundImage = "url('imgs/pic2.jpg')";
   }
  }
 </script>
 <table id="outer">

Я использую аналогичный стиль кодирования, чтобы показать/скрыть кнопку "назад к началу" после определенной позиции прокрутки, которая функционирует просто отлично. Я не думаю, что есть конфликт между ними (хотя встроенный скриптинг не является моим предпочтительным стилем), потому что даже когда я удаляю все, что связано с кнопкой "назад к началу", мой код все еще не работает.

Является ли это глупой синтаксической ошибкой или есть более фундаментальная ошибка для моего подхода?

Теги:
background-image
onscroll

1 ответ

0

Я немного изменил ваш код, и он работает:

jsFiddle 1

var divOuter = document.getElementById("outer"),
	divOne = document.getElementById("one");

window.onscroll = function() {scrollBG()};

  function scrollBG() {
  	var oneTop = divOne.getBoundingClientRect().top;
   if(document.body.scrollTop > oneTop ||
       document.documentElement.scrollTop > oneTop){
       	 divOuter.style.backgroundImage = "url('//www.planwallpaper.com/static/images/518071-background-hd_xO1TwRc.jpg')";
       } else {
       		 divOuter.style.backgroundImage = "url('//www.planwallpaper.com/static/images/maxresdefault_YodSsVN.jpg')"; 
       }
  }
body { margin: 0; padding: 0; height: 1500px; }
#outer {
  position: fixed;
  background: url('//www.planwallpaper.com/static/images/maxresdefault_YodSsVN.jpg') no-repeat;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
#one {
  width: 100%;
  height: 150px;
  background-color: orange;
  color: white;
  position: relative;
  top: 400px;
}
<div id="outer"></div>
<div id="one"><h1>This is One</h1></div>

Однако, следуя приведенному выше методу, будет неэффективно, так как IMHO делает дополнительный HTTP-запрос для изображений каждый раз, когда свиток идет вверх и вниз по порогу, и, таким образом, вы будете видеть мерцание при каждом изменении фоновых изображений.

Поэтому было бы лучше, если бы мы использовали внешний CSS-класс, т. #outer.bg2, и просто добавляем/удаляем его в зависимости от положения прокрутки, и это приведет к кэшированной версии изображения, что делает ее гладкой [ кроме первого раза, когда изображение запрашивается в первый раз]. Как показано ниже:

jsFiddle 2

var divOuter = document.getElementById("outer"),
  divOne = document.getElementById("one");


window.onscroll = function() { scrollBG() };

function scrollBG() {
  var oneTop = divOne.offsetTop;
  if (document.body.scrollTop > oneTop ||
    document.documentElement.scrollTop > oneTop) {
    divOuter.classList.add('bg2');
  } else {
    divOuter.classList.remove('bg2');
  }
}
body{ margin:0; padding:0; height: 1500px; }
#outer{
  position:fixed;
  background: url('//www.planwallpaper.com/static/images/maxresdefault_YodSsVN.jpg') no-repeat;
  top:0;
  left:0;
  right:0;
  bottom:0;
}
#outer.bg2{
  background: url('//www.planwallpaper.com/static/images/518071-background-hd_xO1TwRc.jpg');
}
#one{
  width:100%;
  height:150px;
  background-color:orange;
  color:white;
  position:relative;
  top:400px;
}
<div id="outer"></div>
<div id="one"><h1>This is One</h1></div>

В приведенном выше коде запуск будет происходить, когда свиток встретит нижнюю часть элемента #one, если вы хотите, чтобы запуск #one в соответствии с верхним краем, а затем замените это:

var oneTop = divOne.offsetTop;

С этим:

var oneTop = divOne.offsetTop - divOne.offsetHeight;

jsFiddle 3

  • 0
    Оказывается, мой код был хорош сам по себе - javascript в другом месте мешал. Но ваша идея добавить / удалить и внешний CSS-класс для изменения изображения гораздо приятнее - спасибо вам за это.
  • 0
    Да, это было хорошо, поэтому я сказал « это работает » в первой строке. В любом случае, каждый раз, когда вам нужно «запросить» элемент более одного раза, лучше хранить ваши .getElement[s]By* или .querySelector* в переменных, а не заставлять javascript .querySelector* элемент снова и снова. Добро пожаловать и наслаждайтесь кодированием!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню