使用 JavaScript 检测点击 Iframe

IT技术 javascript iframe ads dom-events click-tracking
2021-01-29 15:05:20

我知道iframe如果是跨域,则无法判断用户在内部做什么我想做的是跟踪用户是否在iframe. 我想象这样一个场景,还有一个看不见div的顶部iframe和的div单击事件只会然后传递给iframe

这样的事情可能吗?如果是,那我该怎么办?iframes是广告,所以我必须在所使用的标签没有控制权。

6个回答

这当然是可能的。这适用于 Chrome、Firefox 和 IE 11(可能还有其他)。

const message = document.getElementById("message");

// main document must be focused in order for window blur to fire when the iframe is interacted with. 
// There's still an issue that if user interacts outside of the page and then click iframe first without clicking page, the following logic won't run. But since the OP is only concerned about first click this shouldn't be a problem.
window.focus()

window.addEventListener("blur", () => {
  setTimeout(() => {
    if (document.activeElement.tagName === "IFRAME") {
      message.textContent = "clicked " + Date.now();
      console.log("clicked");
    }
  });
}, { once: true });
<div id="message"></div>
<iframe width="50%" height="300" src="//example.com"></iframe>

警告:这只检测第一次点击。据我了解,这就是你想要的。

它在 Firefox 中不起作用。JSFiddle 包含隐藏这一点的错误:= 而不是 ===。有跨浏览器解决方案(即使在 IE8 中):stackoverflow.com/a/32138108/1064513
2021-03-17 15:05:20
另外值得注意的是,如果您更改浏览器选项卡,它将触发 focus();
2021-03-31 15:05:20
为什么依赖于 focus();
2021-03-31 15:05:20
如果用户没有先单击主文档,则不会触发模糊事件!此外,这不适用于检测对多个 iframe 的点击,因为当焦点从一个 iframe 更改为另一个 iframe 时,不会触发任何事件(iframe 的blur事件不会触发)。
2021-04-01 15:05:20
@the_joric,这是因为问题已经过去 4 年了,人们通常不会翻过前几个答案。
2021-04-09 15:05:20

基于 Mohammed Radwan 的回答,我想出了以下 jQuery 解决方案。基本上它的作用是跟踪 iFrame 人们正在悬停的内容。然后,如果窗口模糊,则很可能意味着用户单击了 iframe 横幅。

iframe 应该放在一个带有 id 的 div 中,以确保您知道用户单击了哪个 iframe:

<div class='banner' bannerid='yyy'>
    <iframe src='http://somedomain.com/whatever.html'></iframe>
<div>

所以:

$(document).ready( function() {
    var overiFrame = -1;
    $('iframe').hover( function() {
        overiFrame = $(this).closest('.banner').attr('bannerid');
    }, function() {
        overiFrame = -1
    });

...当没有 iFrame 悬停时,这将 overiFrame 保持在 -1,或者在 iframe 悬停时在包装 div 中设置的“bannerid”。您所要做的就是检查窗口模糊时是否设置了“overiFrame”,如下所示:...

    $(window).blur( function() {
        if( overiFrame != -1 )
            $.post('log.php', {id:overiFrame}); /* example, do your stats here */
    });
});

非常优雅的解决方案,但有一个小缺点:如果用户在将鼠标悬停在 iFrame 上时按下 ALT-F4,它会将其记录为点击。这只发生在 FireFox 中,IE、Chrome 和 Safari 没有注册它。

再次感谢穆罕默德,非常有用的解决方案!

这个答案是其中最好的,但是,如果您希望接收对 iframe 的每次点击,您需要在用户点击后将焦点移开,以便监控进一步的点击。这应该被添加到$(窗口).blur()部分:setTimeout(function(){ window.focus(); }, 0);现在,用户点击,将焦点放在 iframe 中,脚本将焦点拉回,现在可以监控未来点击的进一步焦点变化。
2021-03-12 15:05:20
我使用上面的脚本来检测远离我的网站的点击。大多数广告网络现在以框架形式提供横幅广告。如果您在第一次单击离开之前单击一个然后又快速单击另一个,从技术上讲,我想知道您实际留下的最后一次单击。所以在我的情况下,这是想要的行为。它也可以很好地检测移动横幅上的点击。因此必须在执行单击之前立即启动悬停
2021-03-18 15:05:20
@HelpingHand 用户会在 iframe 中失去焦点。想象一下,如果用户在 iframe 中聚焦输入,该方法会让他们失去焦点。奥兹....
2021-03-22 15:05:20
不适用于 iframe 内容中的 svg 元素:( stackoverflow.com/questions/32589735/...
2021-03-28 15:05:20
我已经为这个答案 +1,但它有以下问题: 1. 当有多个 iframe 时,您单击其中一个,然后立即单击另一个 - 未检测到第二次单击。2. iframe 内的多次点击也不计算在内。3.在手机上不能正常工作,因为你不能用手指做“悬停”事件。
2021-04-01 15:05:20

这是一个适用于所有浏览器甚至 IE8 的小解决方案:

var monitor = setInterval(function(){
    var elem = document.activeElement;
    if(elem && elem.tagName == 'IFRAME'){
        clearInterval(monitor);
        alert('clicked!');
    }
}, 100);

你可以在这里测试:http : //jsfiddle.net/oqjgzsm0/

@shankshera 只需获取 elem.id,那是您的 iframe id :)。参见jsfiddle.net/oqjgzsm0/219
2021-03-17 15:05:20
除了以这种速率使用连续循环间隔不是一个好主意之外,如果用户通过 Tab 键导航将焦点设置在 iframe 上,这将检测到误报
2021-03-17 15:05:20
唯一可在最新 FF 中运行的跨浏览器可靠解决方案!多谢。值得更多赞
2021-03-25 15:05:20
我正在使用它来跟踪对社交按钮的点击。但是因为我使用的 3/4 使用 iframe,所以我需要跟踪多个 iframe 中的点击。我已经更新了小提琴以允许:jsfiddle.net/oqjgzsm0/273它设置了一个新的时间间隔,用于检查点击是否在上次点击的 iframe 之外。然后重置原始间隔以再次检查点击。它不会跟踪同一 iframe 中的多次点击而没有在 iframe 之外进行点击。
2021-04-01 15:05:20
如果您有多个 iframe 而您不知道它们的 ID 怎么办?
2021-04-04 15:05:20

这样的事情可能吗?

不。您所能做的就是检测进入 iframe 的鼠标,并且可能(虽然不可靠)当它回来时(即尝试计算出在其他地方经过广告的指针与挥之不去的指针之间的差异)在广告上)。

我想象一个场景,在 iframe 顶部有一个不可见的 div,然后 div 将点击事件传递给 iframe。

不,没有办法伪造点击事件。

通过捕捉mousedown,您将阻止原始点击进入iframe。如果您可以确定鼠标按钮何时将被按下,您可以尝试将不可见的 div 移开,以便点击可以通过……但也没有在鼠标按下之前触发的事件。

您可以尝试猜测,例如通过查看指针是否已停止,猜测可能即将出现点击。但它完全不可靠,如果你失败了,你就失去了一个点击率。

我检查了这些链接,我认为答案是正确的。您只能检测 iframe 内的点击,而不能检测点击的内容。
2021-03-21 15:05:20
我投反对票,只是因为它不完全正确。您所说的大部分内容都是真实的,但是有一些解决方法,就像此线程上更受欢迎的答案一样。
2021-03-26 15:05:20
是的。还有跨浏览器解决方案:stackoverflow.com/a/32138108/1064513
2021-04-01 15:05:20

以下代码将显示用户是否单击/悬停或移出 iframe:-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Detect IFrame Clicks</title>
<script type="text/javascript">
    $(document).ready(function() {
        var isOverIFrame = false;

        function processMouseOut() {
            log("IFrame mouse >> OUT << detected.");
            isOverIFrame = false;
            top.focus();
        }

        function processMouseOver() {
            log("IFrame mouse >> OVER << detected.");
            isOverIFrame = true;
        }

        function processIFrameClick() {
            if(isOverIFrame) {
                // replace with your function
                log("IFrame >> CLICK << detected. ");
            }
        }

        function log(message) {
            var console = document.getElementById("console");
            var text = console.value;
            text = text + message + "\n";
            console.value = text;
        }

        function attachOnloadEvent(func, obj) {
            if(typeof window.addEventListener != 'undefined') {
                window.addEventListener('load', func, false);
            } else if (typeof document.addEventListener != 'undefined') {
                document.addEventListener('load', func, false);
            } else if (typeof window.attachEvent != 'undefined') {
                window.attachEvent('onload', func);
            } else {
                if (typeof window.onload == 'function') {
                    var oldonload = onload;
                    window.onload = function() {
                        oldonload();
                        func();
                    };
                } else {
                    window.onload = func;
                }
            }
        }

        function init() {
            var element = document.getElementsByTagName("iframe");
            for (var i=0; i<element.length; i++) {
                element[i].onmouseover = processMouseOver;
                element[i].onmouseout = processMouseOut;
            }
            if (typeof window.attachEvent != 'undefined') {
                top.attachEvent('onblur', processIFrameClick);
            }
            else if (typeof window.addEventListener != 'undefined') {
                top.addEventListener('blur', processIFrameClick, false);
            }
        }

        attachOnloadEvent(init);
    });
</script>
</head>
<body>
<iframe src="www.google.com" width="100%" height="1300px"></iframe>
<br></br>
<br></br>
<form name="form" id="form" action=""><textarea name="console"
id="console" style="width: 100%; height: 300px;" cols="" rows=""></textarea>
<button name="clear" id="clear" type="reset">Clear</button>
</form>
</body>
</html>

您需要将 iframe 中的 src 替换为您自己的链接。希望这会有所帮助。问候,莫。

基于快速测试,给定的示例(修复 URL 后)似乎在 IE 8 中工作,在 Chrome 14.0.835.186 m 中有些可靠,但在 Firefox 6.0.2 中则完全不可靠。
2021-03-17 15:05:20
适用于 Chrome,但不适用于 Firefox v62,因为单击 iframe 时不会引发模糊事件
2021-04-05 15:05:20