【问题标题】:Make iframe click-through, but not the iframe's body使 iframe 点击,但不是 iframe 的正文
【发布时间】:2017-01-20 14:33:25
【问题描述】:

我怎样才能使 iframe 点击进入,但让 iframe 的正文仍然可以点击?

我试过了:

iframe.style.width = '100%'
iframe.style.height = '100%'
iframe.style.display = 'block'
iframe.style.position = 'fixed'
iframe.style.backgroundColor = 'transparent'
iframe.style.pointerEvents = 'none'
iframe.style.border = '0'
iframe.frameborder = '0'
iframe.scrolling = 'no'
iframe.allowTransparency = 'true'

在我的 I 框架内,我正在使用以下 css:

html, body {
    /* background:none transparent; */
    pointer-events:auto;
}

这会导致 body 可见(这是我想要的),但它像 iframe 的其余部分一样可以点击。我希望 iframe 的主体是可点击的,但实际 iframe 元素的所有其余部分都应该是可点击的。

iframe 总是比它里面的 body 大。

不幸的是,我无法从主站点访问 iframe 内容(因此无法访问 scrollHeight 等),我只能更改其实际源代码。

【问题讨论】:

  • 如果我做对了,你希望 iframe 元素是可点击的,但里面什么都没有?
  • 点击率是什么意思?点击没有事件?
  • @fingeron 我假设他在问,是否可以让 iFrame 中的 HTML 捕获鼠标事件,但是如果 iFrame 中光标触发的位置不存在 HTML 元素,则鼠标事件将通过 iFrame 传递到原始 DOM 上的 HTML。
  • @SilentTremor 'click through' 是指没有捕捉到鼠标事件,就好像该元素不存在一样。
  • Ian Wise 在这两个方面都是正确的,他的假设是我所问的以及在这种情况下“点击”意味着什么。

标签: javascript html css iframe click-through


【解决方案1】:

免责声明: OP 大约在两年前提出了这个问题,我的回答遵循 Ian Wise 提出的问题并详细说明(参见 cmets)。


您在此处描述的内容涉及文档和子文档之间的逻辑:“如果单击事件在子文档中没有执行任何操作,则将该单击事件应用于父文档”,因此无法处理使用 HTML/CSS。

iframe 是不同的文档。它们与其容器确实存在子父关系,但 iframe 内发生的事件将由 iframe 处理。

一个需要一些代码但可行的想法:

  • 在所有堆叠的 iframe 上方放置一个透明 div,然后捕获 点击事件位置。
  • 父逻辑->
    • 遍历现有 iframe 元素的数组。
    • 发送点击位置,直到其中一个 iframe 返回肯定响应。

function clickOnCover(e, i) {
	if(e && e.preventDefaule) e.preventDefault();
	if(i && i >= iframes.length) {
		console.log("No action.");
		return;
	}
	var iframe = iframes[i || 0];
	if(iframe.contentWindow && iframe.contentWindow.postMessage) {
		iframe.contentWindow.postMessage({ x: e.clientX, y: e.clientY, i: i });
	}
}
function iframeResponse(e) {
	var response = e.data, iframeIndex = response.i;
	if(response.success)
		console.log("Action done on iframe index -> " + iframeIndex);
	else 
		clickOnCover({ clientX: response.x, clientY: response.y }, iframeIndex+1);
}
  • iFrames 逻辑 ->
    • 有一个函数接受clientX, clientY 并检查该位置的可能活动(可能很棘手!)。
    • 如果发生操作,将积极响应,反之亦然。

window.addEventListener("message", function(e) {
	// Logic for checking e.x & e.y
	
	e.success = actionExists; // Some indicator if an action occurred.
	
	if(window.parent && window.parent.postMessage) {
		window.parent.postMessage(e);
	}
});

此解决方案持续管理父文档中的事件,并且只需要遍历任何数量的堆叠 iframe。


找到一个相关的 SO 问题以进一步支持我的主张:Detect Click in Iframe

【讨论】:

  • 这里真正的答案是:“你不能”。如果您想要实际的、原始的 isTrusted 指针事件,则不是。你可以得到一个模拟事件,但它不能做原始事件所能做的所有事情,因为它在浏览器和设备级别都有完全不同的限制。它不会是用户发起的事件,而是生成的事件。如果它也指出了这一点,我会说你的答案是完整的。
  • @AndreiGheorghiu 我在“你不能”之后停止阅读 :) 一个人花了很多时间在网上搜索信息,所以我认为这个解决方案对他很重要是安全的。 isTrustedisSafeisPossible 无所谓。如果安全是一个问题,我相信他会采取必要的预防措施。无论如何,我将把决策权留给他,同时尽我所能提供一种可能实现最终目标的方式。不过感谢您的反馈。
  • @AndreiGheorghiu 完整阅读您的消息,请注意我没有要求“模拟”点击事件。我确实建议一些按位置查找元素的逻辑是可取的。
【解决方案2】:

这在 CSS 中是不可能的。
最简单的方法是正确调整 iframe 的大小。假设您可以访问 iframe 内容,则可以使用以下解决方案:

你可以加一点 JS 让父页面知道 iframe 的高度

mainpage.js

var iframe = getIframe();
setIntervalMaybe(() => {
    // ask for size update
    iframe.contentWindow.postMessage({action: "getSize"}, document.location.origin);
}, 100)
window.addEventListener("message", function receiveMessage(event) {
  switch(event.data.action) {
    case "returnSize":
      // updateIFrameSize(event.data.dimensions);
      console.log(event.data.dimensions);
      break;
  }
}, false);

iframe.js

window.addEventListener("message", function receiveMessage(event) {
  switch(event.data.action) {
    case "getSize":
      event.source.postMessage({action: "returnSize", dimensions: {
        width: document.body.offsetWidth,
        height: document.body.offsetHeight
      }}, event.origin);
      break;
  }
}, false);

【讨论】:

  • @fingeron,如果您暗示 Andrii 复制了您的答案,我想指出您的答案不正确,因为它缺乏技术实现(代码)。如果您的答案仅提供一般建议而没有代码,那么任何按照您的建议编写代码的人都可能会提供比您的更有用、因此更有帮助的答案。您不能就建议主张版权,如果有人能够根据您的建议提出更好的答案,我们鼓励他们这样做。
  • 从技术上讲,您甚至不能对代码声明版权。有很多法律先例可以支持我的陈述,但那是完全不同的故事。
  • @fingeron,这是另一个答案,你说的是传递点击事件,我说的是通常的调整大小,这种方法更简单,没有错误,同时做同样的事情
  • @fingeron,顺便说一句,我点赞了你的回答 :-) 这是第一次点赞
  • @AndreiGheorghiu 根据您的有用建议添加了一些代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 2011-11-11
相关资源
最近更新 更多