Метод IntersectionObserver не работает - JavaScript

У меня есть div, который я хочу изменить цвет, когда он прокручивается в область просмотра, и я пытаюсь добиться этого с помощью нового метода intersectionObserver. Я установил свои параметры в обратном вызове config, но я не могу заставить наблюдателя добавить класс для изменения цвета фона?

Любая помощь будет потрясающей.

codepen: https://codepen.io/emilychews/pen/mXVBVK

const config = {
  root: null,  // sets the framing element to the viewport
  rootMargin: '0px',
  threshold: 0.5
};

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

let observer = new IntersectionObserver(function(entries) {
  observer.observe(box);
  entries.forEach(function(item){
    item.classList.add("active");
  });
}, config);
body {
  margin: 0; padding: 0;
  display:flex;
  justify-content: center;
  align-items: center;
  height: 300vh;
}

#box {
  width: 100px; 
  height: 100px;
  background: blue;}

.active {background: red;}
<div id="box"></div>

1 ответ

Решение

Функция внутри IntersectionObserver Конструктор вызывается всякий раз, когда пересечение меняется. Вы не можете положить observer.observe(box); внутри него.

Также, item это не элемент DOM - это IntersectionObserverEntry так что вы не можете использовать .classList в теме. Вы, вероятно, хотели обратиться item.target,

Даже если вышеупомянутое исправлено, ваш CSS не изменится, потому что вы использовали #box селектор для установки background в blue который имеет более высокую специфичность, чем .active, Легко исправить, чтобы изменить #box в .box и как использовать HTML <div id="box" class="box"></div> вместо.

Исправленный код будет выглядеть так:

const config = {
  root: null, // sets the framing element to the viewport
  rootMargin: '0px',
  threshold: 0.5
};

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

let observer = new IntersectionObserver(function(entries) {
  entries.forEach(function(item) {
    item.target.classList.add("active");
  });
}, config);

observer.observe(box);
body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300vh;
}

.box {
  width: 100px;
  height: 100px;
  background: blue;
}

.active {
  background: red;
}
<div id="box" class="box"></div>

Теперь вам нужна логика внутри обратного вызова:

entries.forEach(function(item){ console.log(item);
  if(item.intersectionRatio > 0.5){
    item.target.classList.add("active");
  }
  else{
    item.target.classList.remove("active");
  }
});

Это сделает <div> красный, когда>50% его видно.

const config = {
  root: null, // sets the framing element to the viewport
  rootMargin: '0px',
  threshold: 0.5
};

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

let observer = new IntersectionObserver(function(entries) {
  entries.forEach(function(item) {
    if (item.intersectionRatio > 0.5) {
      item.target.classList.add("active");
    } else {
      item.target.classList.remove("active");
    }
  });
}, config);

observer.observe(box);
body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300vh;
}

.box {
  width: 100px;
  height: 100px;
  background: blue;
}

.active {
  background: red;
}
<div id="box" class="box"></div>

Другие вопросы по тегам