首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >getBoundingClientRect来自于iFrame

getBoundingClientRect来自于iFrame
EN

Stack Overflow用户
提问于 2018-10-30 03:05:27
回答 2查看 3.8K关注 0票数 5

我有一个函数来评估一个元素(一个iFrame)是否在视图中,如果该元素在视图中,它将返回true。

代码语言:javascript
复制
function isElementInViewport() {
    var el = document.getElementById('postbid_if')
    var rect = el.getBoundingClientRect();
    var elemTop = rect.top;
    var elemBottom = rect.bottom;

    console.log("eleTom " + elemTop)
    console.log("elemBottom " + elemBottom)
    console.log("window.innerHeight " + (window.innerHeight + (window.top.innerHeight * 0.5)))

    var isVisible = (elemTop >= 0) && (elemBottom <= (window.innerHeight + window.innerHeight * 0.5));
    return isVisible;
}

此函数在直接送达页面时工作正常,但在活动环境中,当该函数运行时,它位于iFrame中,看起来getBoundingClientRect()引用的是iFrame的视口,而不是主窗口?

是否有任何方法从iFrame和getBoundingClientRect()中使用主窗口视图?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-20 16:36:39

每个iframe都有自己的作用域,因此iframe内部的窗口与根窗口不同。

您可以通过window.top获得根窗口,根据这些知识,您可以计算出当前iframe的绝对位置。以下是一个适当的功能:

代码语言:javascript
复制
function currentFrameAbsolutePosition() {
  let currentWindow = window;
  let currentParentWindow;
  let positions = [];
  let rect;

  while (currentWindow !== window.top) {
    currentParentWindow = currentWindow.parent;
    for (let idx = 0; idx < currentParentWindow.frames.length; idx++)
      if (currentParentWindow.frames[idx] === currentWindow) {
        for (let frameElement of currentParentWindow.document.getElementsByTagName('iframe')) {
          if (frameElement.contentWindow === currentWindow) {
            rect = frameElement.getBoundingClientRect();
            positions.push({x: rect.x, y: rect.y});
          }
        }
        currentWindow = currentParentWindow;
        break;
      }
  }
  return positions.reduce((accumulator, currentValue) => {
    return {
      x: accumulator.x + currentValue.x,
      y: accumulator.y + currentValue.y
    };
  }, { x: 0, y: 0 });
}

现在,在isElementInViewport内部修改这些行:

代码语言:javascript
复制
var elemTop = rect.top;
var elemBottom = rect.bottom;

代码语言:javascript
复制
var currentFramePosition = getCurrentFrameAbsolutePosition();
var elemTop = rect.top + currentFramePosition.y;
var elemBottom = rect.bottom + currentFramePosition.y;

这应该管用。

票数 11
EN

Stack Overflow用户

发布于 2021-10-14 14:54:04

下面是跨域iframes的代码:

代码语言:javascript
复制
window.addEventListener('message', async (event) => {
  if (event.data.channel !== GET_IFRAME_COORDINATES_MESSAGE) return;

  const coordinates = window === window.top
    ? { x: 0, y: 0 }
    : await getFrameCoordinates();

  const iframes = document.getElementsByTagName('iframe');
  for (const iframe of iframes) {
    if (iframe.src !== event.data.href) continue;
    const { x, y } = iframe.getBoundingClientRect();
    event.source.postMessage({
      channel: `${GET_IFRAME_COORDINATES_MESSAGE}-reply`,
      coordinates: {
        x: coordinates.x + x,
        y: coordinates.y + y,
      }
    }, '*');
    break;
  }
});

async function getFrameCoordinates() {
  return new Promise((resolve, reject) => {
    const listenForFrameCoordinatesResponse = (event) => {
      if (event.data.channel !== `${GET_IFRAME_COORDINATES_MESSAGE}-reply`) return;
      window.removeEventListener('message', listenForFrameCoordinatesResponse);
      resolve(event.data.coordinates);
    };
    window.addEventListener('message', listenForFrameCoordinatesResponse);
    window.parent.postMessage({
      channel: GET_IFRAME_COORDINATES_MESSAGE,
      href: window.location.href,
    }, '*');
    setTimeout(() => reject(new Error('Getting frame coordinates timeout')), 2000);
  });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53056796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档