设置根元素时,IntersectionObserver 无法检测到交叉点

IntersectionObserver failling to detect the intersecttion when root element is set

我有一个 IntersectionObserver 观察一个 img 当根设置为 null(视口)时它工作得很好。但是,当我将根元素设置为另一个 img 元素时,观察者无法检测到两者之间的交集。经过几个小时的调试,我决定向社区寻求帮助。

可以从 public 存储库 in this file 中找到代码

为了能见度,我将在此处跳过它:

<template>
  <section
    id="scene"
    class="flex flex-col content-center justify-center items-center mt-16"
    style="height: calc(100% - 4rem)"
  >
    <div id="trigger1"></div>
    <div class="mb-6 mt-32 inset-x-auto">
      <img
        id="logo"
        data-dis-type="simultaneous"
        data-dis-particle-type="ExplodingParticle"
        src="@/static/pure-logo.png"
        class="w-48 relative left-auto inset-y-auto"
        alt="Logo used in the center of the home page"
      />
    </div>
    <div class="inset-x-auto absolute">
      <h1
        class="font-h text-4xl relative"
        id="tagline"
        style="top: 24rem;"
      >Everything begins with an idea.</h1>
    </div>
    <div class data-depth="0.45">
      <img
        style="top: 23rem; transform: scale(1.2, 1.2);"
        src="@/assets/img/forground.png"
        class="w-full relative hidden"
        alt="the forgoround is a picture of a ground covered with leafs"
      />
    </div>
    <div class data-depth="0.5">
      <img
        id="underground"
        style="top: 38rem; transform: scale(1.2, 1.2);"
        src="@/assets/img/underground.png"
        class="w-full relative opacity-25"
        alt="then there is a picture of the underground"
      />
    </div>
  </section>
</template>

<script>
import Parallax from 'parallax-js'
import disintegrate from 'disintegrate'

export default {
  // head() {
  //   return {
  //     script: [{ src: 'http://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.min.js' }]
  //   }
  // },
  // data() {
  //   return {
  //     initialized: false
  //   }
  // },
  components: {},
  mounted() {
    /* eslint-disable no-unused-vars, nuxt/no-env-in-hooks */
    // excute deligters
    // prepare parallex scene
    const parallaxScene = document.getElementById('scene')
    const parallaxInstance = new Parallax(parallaxScene)
    // scroll magic
    // init controller
    const ScrollMagic = require('scrollmagic')
    const controller = new ScrollMagic.Controller()
    const scrollScene = new ScrollMagic.Scene({
      triggerElement: '#trigger1',
      duration: 570,
      triggerHook: 0, // don't trigger until #pinned-trigger1 hits the top of the viewport
      reverse: true
    })
      .setPin('#logo')
      .setClassToggle('#tagline', 'text-blur-out') // add class toggle
      .addTo(controller)

    // creating promises to make sure the scene is loaded and initialized
    // 
    const loaded = new Promise((resolve) => {
      window.addEventListener('disesLoaded', resolve)
    })
    const initialized = new Promise((resolve) => {
      window.addEventListener('disesLoaded', resolve)
    })
    disintegrate.init()
    Promise.all([loaded, initialized]).then(() => {
      if ('IntersectionObserver' in window) {
        console.log('ALL SET')
        const options = {
          root: document.querySelector('#underground'), // relative to underground element
          rootMargin: '-125px 0px 0px 0px', // margin around root. Values are similar to css property. Unitless values not allowed
          threshold: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] // visible amount of item shown in relation to root
        }
        const observer = new IntersectionObserver((changes, observer) => {
          changes.forEach((change) => {
            console.log('TCL: desintegrate -> change.intersectionRatio', change.intersectionRatio)
            const e = document.querySelector('[data-dis-type="simultaneous"]')
            const disObj = disintegrate.getDisObj(e)
            disintegrate.createSimultaneousParticles(disObj)
          })
          console.log('TCL: mounted -> observer', observer)
        }, options)
        observer.observe(document.querySelector('#logo'))
      }
    })
  }
}
</script>

<style>
.debug {
  background-color: red;
  width: 100%;
  height: 2px;
}

#logo {
  pointer-events: all;
}
.scrollmagic-pin-spacer > img {
}
.text-blur-out {
  animation: text-blur-out 1s alternate both;
}

/* ----------------------------------------------
 * Generated by Animista on 2019-7-7 16:39:35
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation text-blur-out
 * ----------------------------------------
 */
@keyframes text-blur-out {
  0% {
    filter: blur(0.01);
  }
  100% {
    filter: blur(12px) opacity(0%);
  }
}
</style>

我认为你的问题是你的 underground 图像不是 logo 图像的后代(而且永远不可能是因为图像不能有祖先)

如果您查看 w3c documentation for IO,您将看到以下内容:

An IntersectionObserver with a root Element can observe any target Element that is a descendant of the root in the containing block chain.

对我来说,这意味着目标元素必须是您观察到的目标元素的后代。