Видимый пересечение Observer - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь узнать о IntersectionObserver в Javascript.

После прочтения нескольких статей и документации я решил создать CodePen, чтобы попробовать сам: IntersectionObserver CodePen

Я бы хотел отобразить «видимый блок» в верхнем сообщении.CodePen «почти» работает, но не полностью.Иногда он показывает правильный блок, иногда нет.

Вот мой JS:

let message = document.querySelector('#block-number');

// INTERSECTION OBSERVER STUFF
const io = new IntersectionObserver(entries => {
   if(entries[0].isIntersecting) {
    message.innerHTML = entries[0].target.textContent;
  }
}, {
    threshold: [.25]
});

// ELEMENTS TO OBSERVE
const blk1 = document.querySelector('#block1');
const blk2 = document.querySelector('#block2');
const blk3 = document.querySelector('#block3');
const blk4 = document.querySelector('#block4');
const blk5 = document.querySelector('#block5');
const blk6 = document.querySelector('#block6');

// START OBSERVING ELEMENTS
io.observe(blk1);
io.observe(blk2);
io.observe(blk3);
io.observe(blk4);
io.observe(blk5);
io.observe(blk6);

Любые идеи о том, что я делаю неправильно?

У меня естьтакже попробовал (без удачи) что-то вроде:

if(entries[0].intersectionRatio !== 0)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 июля 2018

Вы установили порог на 25%.

Проблема в том, что предыдущий блок оставляет свои последние 25% области просмотра после , следующий блок входит в область просмотра с помощью25%.

Это было легко увидеть с помощью следующего файла console.log:

console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)

let message = document.querySelector('#block-number');

// INTERSECTION OBSERVER STUFF
const io = new IntersectionObserver(entries => {
   if(entries[0].isIntersecting ) {
    console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)
    message.innerHTML = entries[0].target.textContent;
  }
}, {
    threshold: [.25]
});

// ELEMENTS TO OBSERVE
const blk1 = document.querySelector('#block1');
const blk2 = document.querySelector('#block2');
const blk3 = document.querySelector('#block3');
const blk4 = document.querySelector('#block4');
const blk5 = document.querySelector('#block5');
const blk6 = document.querySelector('#block6');

// START OBSERVING ELEMENTS
io.observe(blk1);
io.observe(blk2);
io.observe(blk3);
io.observe(blk4);
io.observe(blk5);
io.observe(blk6);
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: roboto;
}

.center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.container {
  background-color: #eee;
  width: 100%;
  height: 100%;
  min-height: 100vh;
}

.message {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  background-color: #ef9b8d;
  color: white;
}

.blocks {
  padding-top: 100px;
}

.block {
  height: 85vh;
  width: 90vw;
  margin: 0 auto 15vh;
  background-color: #999;
  color: white;
}
<div class="message center">Displaying &nbsp;<span id="block-number">Block 1</span></div>
  
  <div class="blocks">
    <div id="block1" class="block center">Block 1</div>
    <div id="block2" class="block center">Block 2</div>
    <div id="block3" class="block center">Block 3</div>
    <div id="block4" class="block center">Block 4</div>
    <div id="block5" class="block center">Block 5</div>
    <div id="block6" class="block center">Block 6</div>
  </div>

Чтобы это исправить, просто поднимите порог .(В зависимости от того, сколько блока нужно ввести в окне просмотра, чтобы считать его текущим блоком)

Демонстрация:

let message = document.querySelector('#block-number');

// INTERSECTION OBSERVER STUFF
const io = new IntersectionObserver(entries => {
   if(entries[0].isIntersecting ) {
    console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)
    message.innerHTML = entries[0].target.textContent;
  }
}, {
    threshold: [.8] // raised the threshold
});

// ELEMENTS TO OBSERVE
const blk1 = document.querySelector('#block1');
const blk2 = document.querySelector('#block2');
const blk3 = document.querySelector('#block3');
const blk4 = document.querySelector('#block4');
const blk5 = document.querySelector('#block5');
const blk6 = document.querySelector('#block6');

// START OBSERVING ELEMENTS
io.observe(blk1);
io.observe(blk2);
io.observe(blk3);
io.observe(blk4);
io.observe(blk5);
io.observe(blk6);
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: roboto;
}

.center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.container {
  background-color: #eee;
  width: 100%;
  height: 100%;
  min-height: 100vh;
}

.message {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  background-color: #ef9b8d;
  color: white;
}

.blocks {
  padding-top: 100px;
}

.block {
  height: 85vh;
  width: 90vw;
  margin: 0 auto 15vh;
  background-color: #999;
  color: white;
}
<div class="message center">Displaying &nbsp;<span id="block-number">Block 1</span></div>
  
  <div class="blocks">
    <div id="block1" class="block center">Block 1</div>
    <div id="block2" class="block center">Block 2</div>
    <div id="block3" class="block center">Block 3</div>
    <div id="block4" class="block center">Block 4</div>
    <div id="block5" class="block center">Block 5</div>
    <div id="block6" class="block center">Block 6</div>
  </div>
0 голосов
/ 13 июня 2018

Функция, переданная в IntersectionObserved, выполняется при изменении состояния пересечения.Так что же происходит, когда вы находитесь в блоке 3 и немного прокручиваете, чтобы показать блок 4?Пересечение изменяется для блока 4, и поэтому сообщение изменяется.Когда вы прокручиваете назад вверх, пересечение снова изменяется для блока 4, но оно не входит в условие if.Перекресток для блока 3, с другой стороны, не изменился - он был виден раньше, хотя и не полностью, он все еще виден.

Существует несколько способов исправить это.Одним из них является определение коэффициента пересечения, и переход выше и ниже этого коэффициента будет считаться изменением состояния (в качестве второго аргумента укажите хэш опций передачи, содержащий ключ threshold со значением 0 - 1, например, 0,5 для видимости 50%)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...