Можно ли применять API Intersection Observer для элементов, которые не являются дочерними?

У меня возникла следующая ситуация: 

1) Я создал сайт.
2) На этом сайте находятся два элемента, которые имеют разных родительских элементов и расположены на значительном расстоянии друг от друга.
3) Первый элемент является фиксированным.
4) Второй элемент - статическим.

Можно ли с помощью Intersection Observer изменить второй элемент, когда он пересекает область первого элемента (которая является регионом наблюдения - root)? 

Я нашел информацию на Хабре, где говорится, что "Intersection Observer API (IOA) позволяет приложению асинхронно наблюдать за пересечением элемента (target) с его родителем (root) или областью просмотра (viewport)". 

Исходя из этой информации, получается, что Intersection Observer не может быть применен для элементов, которые не являются дочерними. Я потратил много времени на поиск решения, даже использовал GPT, который утверждает, что это возможно, но предложенный им код не работает. 

Если это действительно возможно, не могли бы вы предоставить пример кода, чтобы я мог это понять?
  • 20 ноября 2024 г. 1:03
Ответы на вопрос 1
К сожалению, вы правы в том, что API Intersection Observer рассматривает пересечения целевого элемента только с его родительским элементом (root) или областью просмотра (viewport). Таким образом, если у вас есть два элемента, которые находятся на разных уровнях DOM и не являются дочерними друг друга, то вы не можете использовать Intersection Observer для отслеживания пересечения этих элементов напрямую.

Однако вы можете создать решение, которое будет работать, используя более сложную логику. Например, можно использовать события скролла для отслеживания видимости второго элемента относительно первого с помощью расчётов координат. Ниже приведён пример, как это можно реализовать:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Intersection Observer Example</title>
  <style>
    body {
      height: 200vh; /* Делаем страницу длинной */
    }
    #fixedElement {
      position: fixed;
      top: 20px;
      left: 20px;
      width: 100px;
      height: 100px;
      background-color: red;
    }
    #staticElement {
      margin-top: 150vh; /* Располагаем второй элемент внизу страницы */
      width: 100px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>
<body>

<div id="fixedElement">Fixed Element</div>
<div id="staticElement">Static Element</div>

<script>
  const fixedElement = document.getElementById('fixedElement');
  const staticElement = document.getElementById('staticElement');

  window.addEventListener('scroll', () => {
    const fixedRect = fixedElement.getBoundingClientRect();
    const staticRect = staticElement.getBoundingClientRect();

    // Проверяем, пересекаются ли области fixed и static элементов
    if (
      staticRect.top < fixedRect.bottom &&
      staticRect.bottom > fixedRect.top
    ) {
      staticElement.style.backgroundColor = 'green'; // Изменяем цвет, если пересекаются
    } else {
      staticElement.style.backgroundColor = 'blue'; // Сбрасываем цвет, если не пересекаются
    }
  });
</script>

</body>
</html>
```

В этом примере фиксированный элемент (красный) наблюдает за пересечением с статическим элементом (синий) с помощью событий прокрутки. Когда второй элемент входит в область видимости первого элемента, его цвет меняется на зелёный.

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

Если у вас будут дополнительные вопросы, не стесняйтесь спрашивать!
Похожие вопросы