Detect Click into Iframe using JavaScript
Detect Click into Iframe using JavaScript
I understand that it is not possible to tell what the user is doing inside an iframe
if it is cross domain. What I would like to do is track if the user clicked at all in the iframe
. I imagine a scenario where there is an invisible div
on top of the iframe
and the the div
will just then pass the click event to the iframe
.
iframe
iframe
div
iframe
div
iframe
Is something like this possible? If it is, then how would I go about it? The iframes
are ads, so I have no control over the tags that are used.
iframes
17 Answers
17
Is something like this possible?
No. All you can do is detect the mouse going into the iframe, and potentially (though not reliably) when it comes back out (ie. trying to work out the difference between the pointer passing over the ad on its way somewhere else versus lingering on the ad).
I imagine a scenario where there is an invisible div on top of the iframe and the the div will just then pass the click event to the iframe.
Nope, there is no way to fake a click event.
By catching the mousedown you'd prevent the original click from getting to the iframe. If you could determine when the mouse button was about to be pressed you could try to get the invisible div out of the way so that the click would go through... but there is also no event that fires just before a mousedown.
You could try to guess, for example by looking to see if the pointer has come to rest, guessing a click might be about to come. But it's totally unreliable, and if you fail you've just lost yourself a click-through.
This is possible: stackoverflow.com/a/23231136/1212596
– Paul Draper
May 11 '15 at 22:24
Yes, it is. And there is crossbrowser solution: stackoverflow.com/a/32138108/1064513
– Dmitry Kochin
Aug 21 '15 at 10:32
I checked these links and I think the answer is correct. You can only detect a click inside iframe but not what was clicked.
– user568021
Jul 15 '16 at 9:02
Based on Mohammed Radwan's answer I came up with the following jQuery solution. Basically what it does is keep track of what iFrame people are hovering. Then if the window blurs that most likely means the user clicked the iframe banner.
the iframe should be put in a div with an id, to make sure you know which iframe the user clicked on:
<div class='banner' bannerid='yyy'>
<iframe src='http://somedomain.com/whatever.html'></iframe>
<div>
so:
$(document).ready( function()
var overiFrame = -1;
$('iframe').hover( function()
overiFrame = $(this).closest('.banner').attr('bannerid');
, function()
overiFrame = -1
);
...
this keeps overiFrame at -1 when no iFrames are hovered, or the 'bannerid' set in the wrapping div when an iframe is hovered. All you have to do is check if 'overiFrame' is set when the window blurs, like so:
...
$(window).blur( function()
if( overiFrame != -1 )
$.post('log.php', id:overiFrame); /* example, do your stats here */
);
);
Very elegant solution with a minor downside: if a user presses ALT-F4 when hovering the mouse over an iFrame it will log it as a click. This only happened in FireFox though, IE, Chrome and Safari didn't register it.
Thanks again Mohammed, very useful solution!
I see in my stats this got a downvote... ehm... why??
– patrick
Sep 7 '12 at 9:01
Screw that idiot who did that!!!! Great answer though, thanks. :)
– Imtiaz
Oct 24 '13 at 21:46
Works on FF, Chrome, new Opera, IE 11. God bless you :)
– Damonsson
Dec 9 '13 at 22:38
Even works on google AdSense ads :)
– patrick
Jan 15 '15 at 20:42
This answer is the best of them, however, if you wish to receive every click into the iframe, you need to take focus out of it once the user has clicked in order to monitor further clicks. This should be added to the $(window).blur() section:
setTimeout(function() window.focus(); , 0);
. Now, the user clicks, puts focus in the iframe, the script pulls that focus back, and can now monitor further focus changes from future clicks.– HelpingHand
Sep 6 '16 at 15:49
setTimeout(function() window.focus(); , 0);
This is certainly possible. This works in Chrome, Firefox, and IE 11 (and probably others).
focus();
var listener = window.addEventListener('blur', function()
if (document.activeElement === document.getElementById('iframe'))
// clicked
window.removeEventListener('blur', listener);
);
JSFiddle
Caveat: This only detects the first click. As I understand, that is all you want.
Wondering why this answer has 0 upvotes. It really works.
– the_joric
Mar 30 '15 at 11:16
@the_joric, it is because it was 4 years after the question, and people normally don't scroll past the first couple answers.
– Paul Draper
Mar 30 '15 at 18:32
Also of note is that if you changes browser tabs it will fire the focus();
– Linnay
Mar 31 '15 at 4:31
It DOES NOT work in Firefox. JSFiddle contains mistake that conceal this: = instead of ===. There is crossbrowser solution (even in IE8): stackoverflow.com/a/32138108/1064513
– Dmitry Kochin
Aug 21 '15 at 10:34
The blur event doesn't fire if user doesn't click into main document first! Also, this is not usable for detecting clicks to multiple iframes, as there is no event that fires when focus changes from one iframe to another (iframe's
blur
event doesn't fire).– Tomáš Kafka
Feb 17 '16 at 15:43
blur
This is small solution that works in all browsers even IE8:
var monitor = setInterval(function()
var elem = document.activeElement;
if(elem && elem.tagName == 'IFRAME')
clearInterval(monitor);
alert('clicked!');
, 100);
You can test it here: http://jsfiddle.net/oqjgzsm0/
What if you have several iframes and you don't know their id?
– shankshera
Aug 28 '15 at 8:15
This worked perfectly for me. Thank you!
– Inigo
Sep 16 '15 at 16:38
only cross-browser reliable solution that also works in latest FF! Thx a lot. It deserves more upvotes
– BrainOverflow
Oct 12 '15 at 11:33
@shankshera Just get elem.id, that's your iframe id :). See jsfiddle.net/oqjgzsm0/219
– Tomáš Kafka
Feb 17 '16 at 15:35
Apart from the fact that using a continuously looping interval at such rate is not a very good idea, this will detect false positives if user set focus on the iframe through tab key navigation
– Kaiido
Apr 23 '16 at 10:43
The following code will show you if the user click/hover or move out of the 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>
You need to replace the src in the iframe with your own link. Hope this'll help.
Regards,
Mo.
Based on quick testing, the given example (after fixing the URL) seems to work in IE 8, somewhat reliably in Chrome 14.0.835.186 m, but not at all in Firefox 6.0.2.
– Matthew Flaschen
Sep 23 '11 at 23:54
Doesn't seem to work here, with a youtube iframe.
– Anoyz
Oct 10 '13 at 21:26
Just found this solution...
I tried it, I loved it..
Works for cross domain iframes for desktop and mobile!
Don't know if it is foolproof yet
window.addEventListener('blur',function()
if(document.activeElement.id == 'CrossDomainiframeId')
//do something :-)
);
Happy coding
This same answer (maybe a slightly better version) was posted a year earlier here on this same page: stackoverflow.com/a/23231136/470749
– Ryan
Feb 19 '17 at 22:27
You can achieve this by using the blur event on window element.
Here is a jQuery plugin for tracking click on iframes (it will fire a custom callback function when an iframe is clicked) :
https://github.com/finalclap/iframeTracker-jquery
Use it like this :
jQuery(document).ready(function($)
$('.iframe_wrap iframe').iframeTracker(
blurCallback: function()
// Do something when iframe is clicked (like firing an XHR request)
);
);
Awseom library!
– Dmitriy Apollonin
Nov 18 '15 at 17:04
see http://jsfiddle.net/Lcy797h2/ for my long winded solution that doesn't work reliably in 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();
this code does not work on IE8 :(
– Natraj
Mar 6 '13 at 14:18
Its awesome coding man.... what actually i want...+1 to @Omar Jackman.. so much helpful to capture click on youtube advertisement
– saun4frsh
Oct 29 '13 at 13:43
Mohammed Radwan,
Your solution is elegant. To detect iframe clicks in Firefox and IE, you can use a simple method with document.activeElement and a timer, however... I have searched all over the interwebs for a method to detect clicks on an iframe in Chrome and Safari. At the brink of giving up, I find your answer. Thank you, sir!
Some tips:
I have found your solution to be more reliable when calling the init() function directly, rather than through attachOnloadEvent(). Of course to do that, you must call init() only after the iframe html. So it would look something like:
<script>
var isOverIFrame = false;
function processMouseOut()
isOverIFrame = false;
top.focus();
function processMouseOver() isOverIFrame = true;
function processIFrameClick()
if(isOverIFrame)
//was clicked
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);
</script>
<iframe src="http://google.com"></iframe>
<script>init();</script>
You can do this to bubble events to parent document:
$('iframe').load(function()
var eventlist = 'click dblclick
blur focus focusin focusout
keydown keypress keyup
mousedown mouseenter mouseleave mousemove mouseover mouseout mouseup mousemove
touchstart touchend touchcancel touchleave touchmove';
var iframe = $('iframe').contents().find('html');
// Bubble events to parent
iframe.on(eventlist, function(event)
$('html').trigger(event);
);
);
Just extend the eventlist for more events.
I used 'touchend' event and it worked! Your answer helped me a lot!
– user3941146
Jan 14 '16 at 15:47
I ran into a situation where I had to track clicks on a social media button pulled in through an iframe. A new window would be opened when the button was clicked. Here was my solution:
var iframeClick = function ()
var isOverIframe = false,
windowLostBlur = function ()
if (isOverIframe === true)
// DO STUFF
isOverIframe = false;
;
jQuery(window).focus();
jQuery('#iframe').mouseenter(function()
isOverIframe = true;
console.log(isOverIframe);
);
jQuery('#iframe').mouseleave(function()
isOverIframe = false;
console.log(isOverIframe);
);
jQuery(window).blur(function ()
windowLostBlur();
);
;
iframeClick();
This works for me on all browsers (included Firefox)
https://gist.github.com/jaydson/1780598
https://jsfiddle.net/sidanmor/v6m9exsw/
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>
<iframe id="idanmorblog" src="https://sidanmor.com/" style="width:400px;height:600px" ></iframe>
http://jsfiddle.net/QcAee/406/
Just make a invisible layer over the iframe that go back when click and go up when mouseleave event will be fired !!
Need jQuery
this solution don't propagate first click inside 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>
This definitely works if the iframe is from the same domain as your parent site. I have not tested it for cross-domain sites.
$(window.frames['YouriFrameId']).click(function(event) /* do something here */ );
$(window.frames['YouriFrameId']).mousedown(function(event) /* do something here */ );
$(window.frames['YouriFrameId']).mouseup(function(event) /* do something here */ );
Without jQuery you could try something like this, but again I have not tried this.
window.frames['YouriFrameId'].onmousedown = function() do something here
You can even filter your results:
$(window.frames['YouriFrameId']).mousedown(function(event)
var eventId = $(event.target).attr('id');
if (eventId == 'the-id-you-want')
// do something
);
I believe you can do something like:
$('iframe').contents().click(function()function to record click here );
using jQuery to accomplish this.
not working for me.
– harvest316
Oct 31 '12 at 11:26
Didn't work for me either. I sure wish it did.
– Bob Brunius
Feb 8 '13 at 18:17
this only works in same origin iframes
– Colin Su
Apr 17 '14 at 3:23
As found there : Detect Click into Iframe using JavaScript
=> We can use iframeTracker-jquery :
$('.carousel-inner .item').each(function(e)
var item = this;
var iFrame = $(item).find('iframe');
if (iFrame.length > 0)
iFrame.iframeTracker(
blurCallback: function()
// Do something when iFrame is clicked (like firing an XHR request)
onItemClick.bind(item)(); // calling regular click with right context
console.log('IFrameClick => OK');
);
console.log('IFrameTrackingRegistred => OK');
)
Based in the answer of Paul Draper, I created a solution that work continuously when you have Iframes that open other tab in the browser. When you return the page continue to be active to detect the click over the framework, this is a very common situation:
focus();
$(window).blur(() =>
let frame = document.activeElement;
if (document.activeElement.tagName == "IFRAME")
// Do you action.. here frame has the iframe clicked
let frameid = frame.getAttribute('id')
let frameurl = (frame.getAttribute('src'));
);
document.addEventListener("visibilitychange", function ()
if (document.hidden)
else
focus();
);
The Code is simple, the blur event detect the lost of focus when the iframe is clicked, and test if the active element is the iframe (if you have several iframe you can know who was selected) this situation is frequently when you have publicity frames.
The second event trigger a focus method when you return to the page. it is used the visibility change event.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It is possible and there is crossbrowser solution: stackoverflow.com/a/32138108/1064513
– Dmitry Kochin
Aug 21 '15 at 10:32