检测使用JavaScript点击进入Iframe

Rus*_*rry 119 javascript iframe ads click-tracking dom-events

我知道iframe如果它是跨域的话,就不可能告诉用户在内部做了什么.我想要做的是跟踪用户是否完全点击了iframe.我想象这样一个场景,还有一个看不见div的顶部iframe和的div意愿,就在这时,通过点击事件的iframe.

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

Pau*_*per 142

这当然是可能的.这适用于Chrome,Firefox和IE 11(可能还有其他版本).

focus();
var listener = window.addEventListener('blur', function() {
    if (document.activeElement === document.getElementById('iframe')) {
        // clicked
    }
    window.removeEventListener('blur', listener);
});
Run Code Online (Sandbox Code Playgroud)

的jsfiddle


警告:这只会检测到第一次点击.据我所知,这就是你想要的.

  • 它不适用于Firefox.JSFiddle包含隐藏错误的错误:=而不是===.有crossbrowser解决方案(即使在IE8中):http://stackoverflow.com/a/32138108/1064513 (5认同)
  • 如果用户没有先点击进入主文档,则不会触发模糊事件!此外,这不适用于检测多个iframe的点击次数,因为当焦点从一个iframe更改为另一个iframe时,不会触发任何事件(iframe的`blur`事件不会触发). (5认同)
  • 想知道为什么这个答案有0个赞成票.真的行. (3认同)
  • 另外值得注意的是,如果您更改浏览器选项卡,它将触发焦点(); (3认同)

pat*_*ick 106

根据Mohammed Radwan的回答,我提出了以下jQuery解决方案.基本上它的作用是跟踪iFrame人们正在徘徊的东西.然后,如果窗口模糊,那很可能意味着用户点击了iframe横幅.

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

<div class='banner' bannerid='yyy'>
    <iframe src='http://somedomain.com/whatever.html'></iframe>
<div>
Run Code Online (Sandbox Code Playgroud)

所以:

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

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

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

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

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

  • 这个答案是最好的,但是,如果您希望每次点击进入iframe,**一旦用户点击**以便监控进一步的点击,您需要关注它.这应该添加到$(window).blur()部分:`setTimeout(function(){window.focus();},0);`.现在,用户点击,将焦点放在iframe中,脚本将焦点拉回来,现在可以监控未来点击的进一步焦点变化. (6认同)

Dmi*_*hin 79

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

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

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

  • 除了以这样的速率使用连续循环间隔这一事实不是一个好主意,如果用户通过tab键导航设置焦点在iframe上,这将检测误报 (9认同)
  • @shankshera刚刚获得elem.id,这是你的iframe id :).见http://jsfiddle.net/oqjgzsm0/219/ (4认同)
  • 我正在使用它来跟踪对社交按钮的点击。但是因为我使用的 3/4 使用 iframe,所以我需要跟踪多个 iframe 中的点击。我已经更新了小提琴以允许这样做:http://jsfiddle.net/oqjgzsm0/273/。它设置了一个新的时间间隔,用于检查点击是否在上次点击的 iframe 之外。然后重置原始间隔以再次检查点击。它不会跟踪同一 iframe 中的多次点击,除非在 iframe 之外点击一次。 (3认同)
  • 非常感谢您的回答。这很有帮助。我还可以建议对其进行修改,以便使其不仅适用于第一次点击,而且适用于每次点击。在 if 语句中,我们可以使用 elem.blur(); 来代替“clearInterval(monitor);”。 (2认同)

bob*_*nce 37

这样的事情可能吗?

不可以.你所能做的只是检测进入iframe的鼠标,并且当它返回时可能(虽然不可靠)(即试图找出在其他地方传递广告的指针之间的区别而不是余下的在广告上).

我想象一个场景,iframe顶部有一个不可见的div,而div只会将click事件传递给iframe.

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

通过捕获mousedown,您可以阻止原始点击进入iframe.如果您可以确定何时按下鼠标按钮,您可以尝试将不可见的div放在一边,以便点击将通过...但是也没有事件在mousedown之前触发.

您可以尝试猜测,例如通过查看指针是否已经停止,猜测点击可能即将到来.但它完全不可靠,如果你失败了,你就会失去一次点击.

  • 是的.还有crossbrowser解决方案:http://stackoverflow.com/a/32138108/1064513 (4认同)

小智 36

以下代码将显示用户是否单击/悬停或移出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>
Run Code Online (Sandbox Code Playgroud)

您需要使用自己的链接替换iframe中的src.希望这会有所帮助.此致,莫.


小智 11

刚发现这个解决方案......我试过了,我很喜欢它..

适用于桌面和移动设备的跨域iframe!

不知道它是否是万无一失的

window.addEventListener('blur',function(){
      if(document.activeElement.id == 'CrossDomainiframeId'){
        //do something :-)
      }
});
Run Code Online (Sandbox Code Playgroud)

快乐的编码

  • 一年前在同一页面上发布了同样的答案(可能是一个稍好的版本):http://stackoverflow.com/a/23231136/470749 (2认同)

Div*_*com 5

请参阅http://jsfiddle.net/Lcy797h2/,了解我在IE中无法可靠运行的长期解决方案

        $(window).on('blur',function(e) {    
            if($(this).data('mouseIn') != 'yes')return;
            $('iframe').filter(function(){
                return $(this).data('mouseIn') == 'yes';
            }).trigger('iframeclick');    
        });

        $(window).mouseenter(function(){
            $(this).data('mouseIn', 'yes');
        }).mouseleave(function(){
            $(this).data('mouseIn', 'no');
        });

        $('iframe').mouseenter(function(){
            $(this).data('mouseIn', 'yes');
            $(window).data('mouseIn', 'yes');
        }).mouseleave(function(){
            $(this).data('mouseIn', null);
        });

        $('iframe').on('iframeclick', function(){
            console.log('Clicked inside iframe');
            $('#result').text('Clicked inside iframe'); 
        });
        $(window).on('click', function(){
            console.log('Clicked inside window');
            $('#result').text('Clicked inside window'); 
        }).blur(function(){
            console.log('window blur');
        });

        $('<input type="text" style="position:absolute;opacity:0;height:0px;width:0px;"/>').appendTo(document.body).blur(function(){
                $(window).trigger('blur');
            }).focus();
Run Code Online (Sandbox Code Playgroud)


Vin*_*nce 5

您可以通过在window元素上使用blur事件来实现此目的.

这是一个用于跟踪点击iframe的jQuery插件(当点击iframe时它将触发自定义回调函数):https: //github.com/finalclap/iframeTracker-jquery

像这样使用它:

jQuery(document).ready(function($){
    $('.iframe_wrap iframe').iframeTracker({
        blurCallback: function(){
            // Do something when iframe is clicked (like firing an XHR request)
        }
    });
});
Run Code Online (Sandbox Code Playgroud)