How do you fade an asset in/out based on scroll position when scrolling in a container?

Viewed 62

I am trying to emulate what the Wall Street Journal has achieved here (https://www.wsj.com/graphics/donald-trump-potential-conflicts-of-interest/) where upon scrolling, the asset on the right changes.

I have based my code on this jsfiddle (http://jsfiddle.net/avrahamcool/QMsuD/) where I have a container with right and left content, and ideally I would like to have an image on the right that changes based on where the user has scrolled to in the left section- hopefully that makes sense.

* {
  margin: 0;
  padding: 0;
}

html,
body,
.Container {
  height: 100%;
}

.Container:before {
  content: '';
  height: 100%;
  float: left;
}

.Header {
  margin-bottom: 10px;
  background-color: #6ea364;
}

.Content {
  position: relative;
  z-index: 1;
}

.Content:after {
  content: '';
  clear: both;
  display: block;
}

.Wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
}

.Wrapper>div {
  height: 100%;
}

.LeftContent {
  background-color: purple;
  overflow: auto;
}

.RightContent {
  background-color: orange;
  float: right;
  margin-left: 10px;
}
    <div class="Container">
      <div class="Header">
        <p>The Header div height is not fixed (But he can be if you want it to)</p>
        <p>This Layout has been tested on: IE10, IE9, IE8, FireFox, Chrome, Safari, Opera. using Pure CSS 2.1 only</p>
      </div>
      <div class="Content">
        <div class="Wrapper">
          <div class="RightContent">
            <p>You can fix the width of this content.</p>
            <p>if you wont, his width will stretch just as it needs to.</p>
          </div>
          <div class="LeftContent">
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
            <p>this will scroll</p>
          </div>
        </div>
      </div>
    </div>

So when the user reaches a certain point when scrolling the left side, the right will fade into a different image. I don't think I can attach my actual code as it is a university assignment and they are quite strict with this stuff, but it is heavily based on the jsfiddle. I am very stuck, is there a way to achieve this? Thanks in advance, any help is appreciated.

1 Answers

IntersectionObserver will tell you when an element comes into view.

This simple snippet demonstrates this by putting an observer onto three of the paragraphs (those that have a class 'change'). The required color is set in a data attribute. In your example you will want to put the image source (or background url depending on how you want to do it) in a data attribute.

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      rightColumn.style.backgroundColor = entry.target.getAttribute('data-color');
    }
  });
};
const rightColumn = document.querySelector('.RightContent');
const changes = document.querySelectorAll('.change');
const observer = new IntersectionObserver(callback);
changes.forEach(change => {
  observer.observe(change);
});
* {
  margin: 0;
  padding: 0;
}

html,
body,
.Container {
  height: 100%;
}

.Container:before {
  content: '';
  height: 100%;
  float: left;
}

.Header {
  margin-bottom: 10px;
  background-color: #6ea364;
}

.Content {
  position: relative;
  z-index: 1;
}

.Content:after {
  content: '';
  clear: both;
  display: block;
}

.Wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
}

.Wrapper>div {
  height: 100%;
}

.LeftContent {
  background-color: purple;
  overflow: auto;
}

.RightContent {
  background-color: orange;
  float: right;
  margin-left: 10px;
}
<div class="Container">
  <div class="Header">
    <p>The Header div height is not fixed (But he can be if you want it to)</p>
    <p>This Layout has been tested on: IE10, IE9, IE8, FireFox, Chrome, Safari, Opera. using Pure CSS 2.1 only</p>
  </div>
  <div class="Content">
    <div class="Wrapper">
      <div class="RightContent">
        <p>You can fix the width of this content.</p>
        <p>if you wont, his width will stretch just as it needs to.</p>
      </div>
      <div class="LeftContent">
        <p class="change" data-color="orange">this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p class="change" data-color="magenta">this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p class="change" data-color="cyan">this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
        <p>this will scroll</p>
      </div>
    </div>
  </div>
</div>

Related