IntersectionObserver и slot?

Ссылка скопирована
11 февраля 2026 1 ответ

Допустим, инициализируется IntersectionObserver:

const observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => (     entries.forEach(({ target, isIntersecting }) => {         if(isIntersecting){                 // ...                 observer.unobserve(target)             }         }     }) ), {     root: document.querySelector('#root') })

const observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => ( entries.forEach(({ target, isIntersecting }) => { if(isIntersecting){ // ... observer.unobserve(target) } } }) ), { root: document.querySelector('#root') })

Но при этом, при исполнении скрипта - все наблюдаемые элементы являются слотами:

document.querySelectorAll('slot[name]').forEach((slot: Element) => {     observer.observe(slot) })

document.querySelectorAll('slot[name]').forEach((slot: Element) => { observer.observe(slot) })

Сами по себе слоты не имеют (почему?) такого свойства, как видимость в DOM, потому что по-умолчанию их свойство стиля, а именно display - равняется contents (либо они в принципе интерпритируются как заведомо не имеющие видимости в DOM).

Если свойство стиля слота display = contents (по умолчанию) - то эти слоты никогда не будут обработаны обсервером, потому что даже при наведении на них в DOM консоли разработчика - они не имеют никаких (computed) размеров вообще.

Если установить слоту свойство стиля display = initial (например), то он принимает размеры в соответствии с размером содержимого дочернего (дочерних) элемента (элементов), но даже в этом случае, когда этот слот не в пределах зоны видимости обсервера - он всё равно обрабатывается обсервером как видимый.

P.S. Да, я понимаю что можно вместо слотов использовать какой-то div, но всё же.

Дополнительно:

имеются ввиду эти слоты?

  • Антон Шаманов, да.
  • Ответы:

    Сами по себе слоты не имеют (почему?) такого свойства, как видимость в DOM

    ну как бэ потому что это слоты, в них просто подставляется контент.
    Почитай https://developer.mozilla.org/en-US/docs/Web/API/W... для общего понимания

    • Ну вопрос был не в том, для чего они используются по спецификации. Я сразу сказал, что да, вместо них можно использовать любой другой элемент. Вопрос был в том, почему при инъекции их в DOM - они не имеют изначально видимости, но когда ты устанавливаешь им свойство видимости (display) отличное от того, которое устанавливает им браузер (в моём случает chrome/canary) - они ВСЕ интерпритируются как видимые, даже когда они не попадают в обозначенную зону видимости обсервером.
    • ты спрашиваешь что-то в духе "почему если колоть микроскопом орехи они раскалываются?"
    • Антон Шаманов, я не буду отвечать на этот вопрос. Суть моего вопроса была в том, что почему один и тот-же элемент, валидный, вроде как, по спецификации - при дефолтном свойстве видимости не виден обсерверу, а при кастомном свойстве стиля - виден он и все ему подобные, которые даже не видны обсерверу.
    • Антон Шаманов, если нужны сурсы для полного понимания, то:
      // client.tsx import { hydrate as hydrateElement } from 'preact'  const observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => (     entries.forEach(({ target, isIntersecting }) => {         if(isIntersecting){             console.log(isIntersecting)             if(target.localName === 'slot'){                 const slotName = target.getAttribute('name')                 if(slotName){                     import(`/dist/islands/island.${ slotName }.js`).then((exports) => {                         const Island = slotName in exports ? exports[slotName] : null                         if(Island){                             hydrateElement(                                 <Island/>, target                             )                         }                     }).catch(error => console.warn(error))                 }                 observer.unobserve(target)             }         }     }) ), {     root: document.querySelector('#root') })  document.querySelectorAll('slot[name]').forEach((slot: Element) => {     observer.observe(slot) })

      // client.tsx import { hydrate as hydrateElement } from 'preact' const observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => ( entries.forEach(({ target, isIntersecting }) => { if(isIntersecting){ console.log(isIntersecting) if(target.localName === 'slot'){ const slotName = target.getAttribute('name') if(slotName){ import(`/dist/islands/island.${ slotName }.js`).then((exports) => { const Island = slotName in exports ? exports[slotName] : null if(Island){ hydrateElement( <Island/>, target ) } }).catch(error => console.warn(error)) } observer.unobserve(target) } } }) ), { root: document.querySelector('#root') }) document.querySelectorAll('slot[name]').forEach((slot: Element) => { observer.observe(slot) })

      // Island.tsx export const Island = ({ name, children, ...props } : { name: string, children: any, props?: any }) => {     const slotStyle = { display: 'initial' }     return (         <slot name={ name } style={ slotStyle } { ...props }>             { children }         </slot>     ) }

      // Island.tsx export const Island = ({ name, children, ...props } : { name: string, children: any, props?: any }) => { const slotStyle = { display: 'initial' } return ( <slot name={ name } style={ slotStyle } { ...props }> { children } </slot> ) }

    • Евгений, там shadow dom
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Дмитрий К. Ответ

    IntersectionObserver и slot - это два разных концепта веб-разработки, которые могут быть использованы вместе для создания более гибкого и производительного интерфейса.

    IntersectionObserver - это API, которое позволяет отслеживать видимость элементов на странице относительно видимой области браузера. Это особенно полезно для ленивой загрузки изображений или других ресурсов, а также для создания бесконечного прокручивания страницы.

    Пример использования IntersectionObserver в JavaScript:

    // Создаем новый экземпляр IntersectionObserver
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // Код, который будет выполнен при попадании элемента в область видимости
        }
      });
    });
     
    // Начинаем отслеживать элемент
    const element = document.querySelector('.element');
    observer.observe(element);

    // Создаем новый экземпляр IntersectionObserver const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { // Код, который будет выполнен при попадании элемента в область видимости } }); }); // Начинаем отслеживать элемент const element = document.querySelector('.element'); observer.observe(element);

    Slot - это элемент веб-компонента, который позволяет встраивать в него контент извне. Слоты позволяют создавать более гибкие и переиспользуемые компоненты, так как разработчик может передавать контент внутрь компонента без необходимости изменения его структуры.

    Пример использования слотов во веб-компонентах:

     
      <div>Содержимое, которое будет вставлено в слот</div>

    <div>Содержимое, которое будет вставлено в слот</div>

    Если вам нужно отслеживать видимость элементов на странице и вставлять в них контент извне, то можно комбинировать использование IntersectionObserver и слотов. Например, вы можете использовать IntersectionObserver для отслеживания видимости элемента и вставлять в него контент через слот в зависимости от его видимости.

    Надеюсь, что эта информация поможет вам понять, как использовать IntersectionObserver и слоты вместе для создания более интересных и функциональных веб-интерфейсов. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их!

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно