我有一个函数来评估一个元素(一个iFrame)是否在视图中,如果该元素在视图中,它将返回true。
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()中使用主窗口视图?
发布于 2018-12-20 16:36:39
每个iframe都有自己的作用域,因此iframe内部的窗口与根窗口不同。
您可以通过window.top获得根窗口,根据这些知识,您可以计算出当前iframe的绝对位置。以下是一个适当的功能:
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内部修改这些行:
var elemTop = rect.top;
var elemBottom = rect.bottom;至
var currentFramePosition = getCurrentFrameAbsolutePosition();
var elemTop = rect.top + currentFramePosition.y;
var elemBottom = rect.bottom + currentFramePosition.y;这应该管用。
发布于 2021-10-14 14:54:04
下面是跨域iframes的代码:
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);
});
}https://stackoverflow.com/questions/53056796
复制相似问题