Изменение фона при скролле

390
14 сентября 2017, 14:59

Хочу реализовать следующее - при достижении определенной секции на сайте, например "<div id="client"></div>", менялся фон на сайте. Пока делаю простенький пример с 2-мя секциями

$(document).ready(function() { 
  now = 1; 
 
  function func(selector, number_photo) { 
 
    var target = $(selector); 
    var targetPos = target.offset().top; 
    var winHeight = $(window).height(); 
    var scrollToElem = targetPos - winHeight; 
 
    $(window).scroll(function() { 
 
      var winScrollTop = $(this).scrollTop(); 
 
      if (winScrollTop > scrollToElem + scrollToElem * 2) { 
 
        if (!(now == number_photo)) { 
          $('body').removeClass('back' + now); 
          $('body').addClass('back' + number_photo); 
          now = number_photo; 
        } 
      } 
    }); 
  } 
 
  $(window).scroll(function() { 
    func('#main', 1); 
    func('#clients', 2); 
  }); 
 
});
body { 
  margin: 0; 
  background-image: url("/Anime/images/top-slider/1.jpg"); 
  background-repeat: no-repeat; 
  background-size: 100% !important; 
  background-attachment: fixed; 
  transition: background 2s linear; 
} 
 
.back1 { 
  background-image: url("/Anime/images/top-slider/1.jpg"); 
} 
 
.back2 { 
  background-image: url("/Anime/images/top-slider/2.jpg"); 
} 
 
#main { 
  height: 900px; 
} 
 
#clients { 
  height: 800px; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div id="main"> 
  MAIN 
</div> 
 
<div id="client"> 
  CLIENT 
</div>

Проблема заключается в следующем, пока не закончится переход на 2-ю картинку, то при скролле, заново начинается переход на эту же 2-ю картинку.

Answer 1

В вашем примере добавляется каждый раз новый обработчик на событие scroll, а еще вы внутри самого обработчика события scroll через функцию добавляете новые обработчики события scroll...

Я просто переписал начисто, надеюсь комментариев достаточно. Решение без jQuery, на HTML5, если нужна поддержка старых браузеров - будет несложно поменять некоторые конструкции на jQuery, я же этого делать не стал, так как в вопросе не требовалось.

(function () { 
  // Массив элементов блоков ([0]) и классов ([1]), которые они применяют к body 
  var blocks = [ 
    [ document.querySelector("#id-1"), "deep-purple" ], 
    [ document.querySelector("#id-2"), "green" ], 
    [ document.querySelector("#id-3"), "deep-orange" ], 
  ]; 
 
  // Последний выбранный блок - используется для того, чтобы лишний раз не менять классы, если блок не сменился при прокрутке 
  var lastBlock = null; 
 
  // Функция, определяющая, какой блок сейчас "виден" 
  // Выбирает блок, средина которого находится ближе всего к средине экрана 
  function updateBodyBackground() { 
    // Ищем блок, который сейчас находится ближе всего к центру экрана 
    var screenCenterHeight = document.body.scrollTop + window.innerHeight / 2; 
    var nearestBlock = null; 
    var nearestDistance; 
    blocks.forEach(function(block) { 
      var blockCenterHeight = block[0].offsetTop + block[0].offsetHeight / 2; 
      var distance = Math.abs(blockCenterHeight - screenCenterHeight); 
      if (nearestBlock == null || distance < nearestDistance) { 
        nearestDistance = distance; 
        nearestBlock = block; 
      } 
    }); 
 
    if (nearestBlock != lastBlock) { 
      // Если это не тот же блок, что был раньше, действуем 
      lastBlock = nearestBlock; 
 
      // Убираем старые классы всех блоков 
      blocks.forEach(function(block) { 
        document.body.classList.remove(block[1]); 
      }); 
 
      // Добавляем текущий 
      document.body.classList.add(nearestBlock[1]); 
    } 
  } 
 
  // Вызываем во время прокрутки страницы 
  document.addEventListener('scroll', updateBodyBackground); 
 
  // Вызываем сразу при загрузке стрианицы 
  updateBodyBackground(); 
 
  // ... можно динамически добавлять / убирать блоки, изменяя элементы массива blocks и вызывая после этого updateBodyBackground() 
})();
body, html { 
  margin:0; 
  padding:0; 
} 
body.deep-purple { 
  background-color:#512DA8; 
} 
body.green { 
  background-color:#388E3C; 
} 
body.deep-orange { 
  background-color:#E64A19; 
} 
 
.block { 
  height:1000px; 
  text-align:center; 
  font-size:72px; 
  line-height:1000px; 
  color:#fff; 
  text-shadow:0 5px 0 rgba(0,0,0,0.14); 
  border-bottom:1px solid #000; 
}
<!DOCTYPE HTML> 
<html> 
	<head></head> 
	<body> 
		<div id="id-1" class="block">1</div> 
		<div id="id-2" class="block">2</div> 
		<div id="id-3" class="block">3</div> 
	</body> 
</html>

READ ALSO
Цвет заменяющего текста в инпуте

Цвет заменяющего текста в инпуте

У меня стоит белый текст в поиске :

262
На новых Super Retina Display (Iphone X) растровый пиксель (bitmap pixel) так же умножается на 4?

На новых Super Retina Display (Iphone X) растровый пиксель (bitmap pixel) так же умножается на 4?

На новых Super Retina Display (Iphone X) растровый пиксель (bitmap pixel) так же умножается на 4?

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

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

Верстаю макетМне нужно, чтобы при уменьшении экрана, начиная с 768px, navbar скрывался и появлялось стилизованное hamburger-menu

243
Стили для содержимиого iframe

Стили для содержимиого iframe

Есть у меня <iframe>, есть ли способы в изменять стили его содержимого? Поменять стили в самой страничке, которая подгружается в iframe нет возможности

245