3

当整个元素都在视口中时,交点观察者很容易分辨出来。代码大致是这样的:

// get an element
const thingIWantEntirelyInView = $("#Thing")[0];  

const checkInView = new IntersectionObserver((event) => {
  console.log("It's in view");
}, {
  root: null, // viewport
  threshold: 1.0,
});
checkInView.observe(thingIWantEntirelyInView);

不过,我想不通的是如何翻转它,所以它不像包含,更像是覆盖。我想知道我的元素(大于视口)何时完全覆盖屏幕。

我尝试切换nullthingIWantEntirelyInView以上的位置,但没有奏效。

我还尝试在页面上添加一个位置固定height: 100vh; width: 100vw元素并检查与该元素的交集,但似乎交集观察者不适用于两个没有父子关系的元素?也许我做错了代码,但这里有一个例子:

const thingIWantFillingView = document.getElementById("BigScrolly");
const viewPort = document.getElementById("ViewPort");  

// what I tried
const checkInView = new IntersectionObserver((event) => {
  console.log("This never seems to happen never happen");
}, {
  root: thingIWantFillingView,
  threshold: 0.5,
});
// when the viewport is at least half inside BigScrolly
checkInView.observe(viewPort);



// example of the thing I don't want
const checkTouchView = new IntersectionObserver((event) => {
  console.log("It has touched the viewport");
}, {
  root: null,
  threshold: 0,
});
// when BigScrolly has touched the viewport
checkTouchView.observe(thingIWantFillingView);
#ViewPort {
  position: fixed;
  height: 100vh;
  width: 100vw;
  top: 0px;
  left: 0px;
  pointer-events: none;
  border: 2px solid red;
  box-sizing: border-box;
}

#SomePreviousThing {
  height: 100vh;
}

#BigScrolly {
  height: 300vh;
  background: linear-gradient(#FFEEEA, #222);
}
<div id="ViewPort"></div>
<div id="SomePreviousThing">
  Ignore this section, scroll down.
</div>
<div id="BigScrolly"></div>

如何使用 Intersection Observers 判断我的元素之一何时完全覆盖屏幕?

4

2 回答 2

3

想出了一个解决方案:我在 BigScrolly 中有一个100vh很高的粘性元素(确保包裹在一个绝对定位的元素中以否定它在流中的位置)。只要我完全滚动到该部分,它就会占据整个视图。

const coverChecker = document.querySelector(".CoverChecker");


// what I tried
const checkInView = new IntersectionObserver((event) => {
  const coverage = event[0].intersectionRatio;
  if (coverage >= 1) {
    console.log("BigScrolly covers the viewport");
  } else {
    console.log("Coverage", event[0].intersectionRatio);
  }
}, {
  root: null,
  threshold: [0, 0.25, 0.5, 0.75, 1.0],
});
// when the viewport is at least half inside BigScrolly
checkInView.observe(coverChecker);
.Positioner {
  position: absolute;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
  pointer-events: none;
}

.CoverChecker {
  position: sticky;
  height: 95vh;
  width: 95vw;
  border: 2px solid red;
  box-sizing: border-box;
  top: 2px; 
}


.OtherSection {
  height: 100vh;
}

#BigScrolly {
  position: relative;
  height: 300vh;
  padding: 20px;
  background: linear-gradient(#FFEEEA, #222);
}
<div class="OtherSection">
  Ignore this section, scroll down.
</div>
<div id="BigScrolly">
  <div class="Positioner">
    <div class="CoverChecker"></div>
  </div>
  This is some text
</div>
<div class="OtherSection">
  Ignore this section, scroll tup.
</div>

于 2019-07-05T03:41:52.377 回答
0

您可以通过简单地检查是否intersectionRect.top为零(并检查是否有任何交集)来实现这一点:

new IntersectionObserver((entries) => {
  entries.forEach( entry => {
    if (entry.intersectionRatio == 0) {
      console.log('not visible at all')
      return
    }
    if (entry.intersectionRect.top == 0) {
      console.log('at the top of the viewport')
      return
    }
    console.log('partially visible — not at the top of the viewport')
  })
})

这是一个完整的示例 - 我使用它来反转浮动页面标题,而页面的黑暗部分位于标题下方:https ://jsfiddle.net/okvtm7gc/

于 2021-05-09T23:41:00.853 回答