You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用getBoundingClientRect()检测iframe视口时触发函数不存在错误

问题分析与解决方案

核心错误

你触发getBoundingClientRect() is not a function的原因很直接:你在自己定义的players[i]对象上调用了这个方法,但这个对象不是DOM元素。players数组里的每一项是你手动创建的包含player、top、status的自定义对象,而getBoundingClientRect()是DOM元素的专属方法,自定义对象自然没有这个方法。

修复步骤

1. 保存iframe DOM元素引用

在构建players数组时,把对应的iframe元素也存进去,这样后续就能直接调用getBoundingClientRect():

var players = []
$("iframe").each((index) => {
  const iframe = $("iframe").get(index);
  players.push({
    player: new Vimeo.Player(iframe),
    iframe: iframe, // 新增:保存DOM元素引用
    status: "paused",
  });
});

2. 修正视口检测逻辑

在scroll事件里,对保存的iframeDOM元素调用getBoundingClientRect(),同时完善视口交集的判断逻辑(你原来的判断只比较了单一数值,无法准确判断元素是否进入视口):

$(window).on('scroll', function() {
  for (var i = 0; i < players.length; i++) {
    const rect = players[i].iframe.getBoundingClientRect();
    // 判断元素是否与视口有交集:元素底部大于0,顶部小于视口高度
    const isInViewport = rect.bottom > 0 && rect.top < window.innerHeight;
    const status = isInViewport ? "play" : "pause";
    
    if (players[i].status !== status) {
      players[i].status = status;
      players[i].player[status]();
      console.log(i, status);
    }
  }
});

更优方案:使用IntersectionObserver

scroll事件会频繁触发,性能较差。推荐使用IntersectionObserverAPI,它专门用于监听元素是否进入视口,性能更优:

var players = []
$("iframe").each((index) => {
  const iframe = $("iframe").get(index);
  const player = new Vimeo.Player(iframe);
  players.push({ player, iframe, status: "paused" });

  // 创建观察者:元素10%进入视口时触发
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      const status = entry.isIntersecting ? "play" : "pause";
      const targetPlayer = players.find(p => p.iframe === entry.target);
      if (targetPlayer && targetPlayer.status !== status) {
        targetPlayer.status = status;
        targetPlayer.player[status]();
        console.log(index, status);
      }
    });
  }, { threshold: 0.1 });

  observer.observe(iframe);
});

额外注意点

  • 你的HTML里存在多余的闭合标签</div>和空的<img>标签,建议清理,避免潜在布局问题
  • Vimeo播放器的play()和pause()方法是异步的,若需要等待执行结果,可结合await处理,当前写法无需等待时可正常使用

内容的提问来源于stack exchange,提问作者Robert Carmichael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:17:07