Different callbacks for different targets with Int

2019-08-23 07:54发布

问题:

I'm using the Intersection Observer API on a site. For every instance of using it, I'm using the same config (main viewport). My issue is that I need to have different things happen when the callback is fired. For some, I want to lazy load an image. For some, I want to initialize a carousel, etc.

Is there a way to use the same observer for all of these different applications or do I have to use a different observer for each unique callback?

回答1:

You can reuse the same intersection observer and same callback for all your different targets, since the callback is provided the target element you can use that information to customize what the callback does.

In example below I change the message on the screen depending on which differently colored div is in view reusing the same IntersectionObserver instance and same callback function:

const message = document.getElementById('message');

function callbackRouter(entries, observer) {
  let entry = entries[0];
  let target = entry.target;
  if (entry.intersectionRatio > 0) {
    message.textContent = target.classList + " is in view!";
    if (target.dataset.callback) {
      window[target.dataset.callback](target);
    }
  }
}

function lazyLoadImage(target) {
    console.log('lazy load an image here');
}

function initCarousel(target) {
  console.log('initialize a carousel here');
}

function sendAsyncRequest(target) {
  console.log('send an async request here');
}

function doWhatever(target) {
  console.log('literally do whatever you want');
}

const observer = new IntersectionObserver(callbackRouter);
const boxes = document.querySelectorAll('.box');
boxes.forEach(observer.observe.bind(observer));
.box {
  height: 1000px;
}

.violet {
  background-color: violet;
}

.green {
  background-color: green;
}

.tomato {
  background-color: tomato;
}

.orange {
  background-color: orange;
}

#message {
  position: fixed;
  top: 20px;
  left: 20px;
  background-color: white;
  height: auto;
  padding: 10px 20px;
}
<div class="tomato box" data-callback="lazyLoadImage"></div>
<div class="violet box" data-callback="initCarousel"></div>
<div class="orange box" data-callback="sendAsyncRequest"></div>
<div class="green box" data-callback="doWhatever"></div>
<div id="message"></div>