Changing background-image onscroll

懵懂的女人 提交于 2019-12-11 08:01:24

问题


I'm trying to change the background image of an element after a certain position has been scrolled past. Here's a snippet of my code:

<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">

I'm using a similar coding style to show/hide a "back to top" button after a certain scroll position that functions just fine. I don't think there's a conflict between the two (though inline scripting isn't my preferred style) because even when I remove everything related to the "back to top" button, my code still fails to function.

Is this a stupid syntactical error, or is there a more fundamental error to my approach?


回答1:


I've tweaked your code a little and it's working:

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>

However, following the above method will be inefficient as IMHO it makes an extra HTTP request for the images every time the scroll goes up and down the threshold and thus you'll see flickering every time the background images get changed.

So it'd be better if we make use of an external CSS class, i.e #outer.bg2, and just add/remove it depending on the position of the scroll and this will fetch a cached version of the image which makes it smooth [except for the first time when the image is being requested for the first time]. Like below:

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>

In the above code the triggering will happen when the scroll meets the bottom of the element #one, if you want the triggering to happen according to the top edge then replace this:

var oneTop = divOne.offsetTop;

With this:

var oneTop = divOne.offsetTop - divOne.offsetHeight;

jsFiddle 3



来源:https://stackoverflow.com/questions/44371552/changing-background-image-onscroll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!