我知道如果iframe
是跨域的,就无法判断用户在其中做了什么。我想要做的是追踪用户是否在iframe
中点击了任何内容。我设想的情况是在iframe
上方有一个不可见的div
,然后div
将点击事件传递给iframe
。
这种方法是否可行?如果可行,我该如何实现?这些iframes
是广告,所以我无法控制所使用的标签。
我知道如果iframe
是跨域的,就无法判断用户在其中做了什么。我想要做的是追踪用户是否在iframe
中点击了任何内容。我设想的情况是在iframe
上方有一个不可见的div
,然后div
将点击事件传递给iframe
。
这种方法是否可行?如果可行,我该如何实现?这些iframes
是广告,所以我无法控制所使用的标签。
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>
这是一个小解决方案,在所有浏览器中都可以工作,甚至在IE8中也可以:
var monitor = setInterval(function(){
var elem = document.activeElement;
if(elem && elem.tagName == 'IFRAME'){
clearInterval(monitor);
alert('clicked!');
}
}, 100);
您可以在这里进行测试:http://jsfiddle.net/oqjgzsm0/
<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没有注册它。
再次感谢Mohammed,非常有用的解决方案!
setTimeout(function(){ window.focus(); }, 0);
。现在,用户点击时,将焦点置于iframe中,脚本会将焦点拉回,并能够监视未来点击事件的焦点变化。 - HelpingHand这种情况可能吗?
不可能。你只能检测鼠标进入 iframe 的事件,而且很难(并非可靠地)检测到鼠标离开 iframe 的事件(例如:试图区分光标经过广告然后去其他地方和光标停留在广告上的区别)。
我想象一种场景,在 iframe 上方有一个透明的 div,然后该 div 只是将点击事件传递到 iframe。
不行,无法伪造点击事件。
通过捕获 mousedown 事件,您将阻止原始点击事件传递到 iframe。如果您可以确定鼠标按钮即将被按下的时间点,您可以尝试将无形的 div 移开,以便点击可以穿过...但是没有在 mousedown 之前触发的事件。
您可以尝试猜测,例如通过查看指针是否停止移动,猜测可能会发生点击事件。但其完全不可靠,如果猜错了,您将失去一个点击连接。
<!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。希望这能帮到您。 问候, Mo。
刚找到了这个解决方案... 我尝试了一下,很喜欢它...
适用于桌面和移动端的跨域iframe!
不知道是否百分百可靠
window.focus();
window.addEventListener('blur',function(){
if(document.activeElement.id == 'CrossDomainiframeId'){
//do something :-)
}
});
愉快地编码
window.focus();
,否则您必须在单击iframe之前在网站中点击一些内容。 - GrantjQuery(document).ready(function($){
$('.iframe_wrap iframe').iframeTracker({
blurCallback: function(){
// Do something when iframe is clicked (like firing an XHR request)
}
});
});
请查看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();
var myConfObj = {
iframeMouseOver : false
}
window.addEventListener('blur',function(){
if(myConfObj.iframeMouseOver){
console.log('Wow! Iframe Click!');
}
});
document.getElementById('idanmorblog').addEventListener('mouseover',function(){
myConfObj.iframeMouseOver = true;
});
document.getElementById('idanmorblog').addEventListener('mouseout',function(){
myConfObj.iframeMouseOver = false;
});
<iframe id="idanmorblog" src="https://sidanmor.com/" style="width:400px;height:600px" ></iframe>
<iframe id="idanmorblog" src="https://sidanmor.com/" style="width:400px;height:600px" ></iframe>
http://jsfiddle.net/QcAee/406/
只需在iframe上覆盖一个不可见的层,在单击时返回并在触发mouseleave事件时向上移动!
需要使用jQuery。
此解决方案不会在iframe内传播第一次点击!
$("#invisible_layer").on("click",function(){
alert("click");
$("#invisible_layer").css("z-index",-11);
});
$("iframe").on("mouseleave",function(){
$("#invisible_layer").css("z-index",11);
});
iframe {
width: 500px;
height: 300px;
}
#invisible_layer{
position: absolute;
background-color:trasparent;
width: 500px;
height:300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message"></div>
<div id="invisible_layer">
</div>
<iframe id="iframe" src="//example.com"></iframe>