Skip to content

Instantly share code, notes, and snippets.

@jaydson
Created February 9, 2012 15:11
Show Gist options
  • Save jaydson/1780598 to your computer and use it in GitHub Desktop.
Save jaydson/1780598 to your computer and use it in GitHub Desktop.
How to detect a click event on a cross domain iframe
var myConfObj = {
iframeMouseOver : false
}
window.addEventListener('blur',function(){
if(myConfObj.iframeMouseOver){
console.log('Wow! Iframe Click!');
}
});
document.getElementById('YOUR_CONTAINER_ID').addEventListener('mouseover',function(){
myConfObj.iframeMouseOver = true;
});
document.getElementById('YOUR_CONTAINER_ID').addEventListener('mouseout',function(){
myConfObj.iframeMouseOver = false;
});
@Toniiiio
Copy link

Toniiiio commented Sep 4, 2017

@AlexandraKlein:
Just initialize iframeMouseOver as true?

@micdenny
Copy link

I did a simple angular wrapper based on these suggestions: https://gist.github.com/micdenny/db03a814eaf4cd8abf95f77885d9316f so you can do this:

<div>
  <iframe appIframeTracker (iframeClick)="onIframeClick()" src="http://www.google.com"></iframe>
</div>

@maxyharr
Copy link

Thanks for the solutions, but are there any that provide mobile support?

@chaitanya1248
Copy link

chaitanya1248 commented Jan 29, 2018

@maxyharr - Use touch events in case of mobile. touchstart, touchend.

https://developer.mozilla.org/en-US/docs/Web/API/Touch_events

@manjeetglv
Copy link

@alucidwolf did you find any solution?

@Pretorians
Copy link

Hi,
Solve the problem in this way for mobile and desktop.

$(document).ready(function()
 {
	window.addEventListener('blur',function(){		
	    if (document.activeElement instanceof HTMLIFrameElement) {
                //Click in Iframe.
	    	tagueoFocusForm("campo captcha no robot");
	    }
	});	
});

@gsumit1
Copy link

gsumit1 commented May 30, 2018

window.addEventListener('blur',function(){
if (document.activeElement instanceof HTMLIFrameElement)
some code}

This content.js code is not working for firefox though it is working for chrome. The web page is consisted of multiple iframes. Any suggestion.

@dawaltconley
Copy link

dawaltconley commented Jun 4, 2018

For me, adding a 0 second timeout to @Pretorians suggestion made it work in Firefox. The problem seems to be that, at the time Firefox fires the blur event, it has not yet updated the document.activeElement, so it evaluates to false.

	window.addEventListener('blur',function(){	
            window.setTimeout(function () {	
	        if (document.activeElement instanceof HTMLIFrameElement) {
	    	    console.log("iframe click");
	        }
             }, 0);
	});

@MichVollmer
Copy link

As alucidwolf, I am looking for a way to access a button inside the iFrame and trigger a click event when that button is clicked inside the iFrame that is on another domain.

Has anyone had success taking it this far?

Michael

@bees4ever
Copy link

Wow nice trick 👍

@sleshJdev
Copy link

This solution is not working for FF v62, because when you click on iframe and redirecting to a new window/tab, blur event in not thrown. Unfortunately I didn't fund any workaround yet.

@sleshJdev
Copy link

sleshJdev commented Oct 4, 2018

Here is how I track iframe click for FF/Chrome:

function () {
    const state = {};

    (function (setup) {
        if (typeof window.addEventListener !== 'undefined') {
            window.addEventListener('load', setup, false);
        } else if (typeof document.addEventListener !== 'undefined') {
            document.addEventListener('load', setup, false);
        } else if (typeof window.attachEvent !== 'undefined') {
            window.attachEvent('onload', setup);
        } else {
            if (typeof window.onload === 'function') {
                const oldonload = onload;
                window.onload = function () {
                    oldonload();
                    setup();
                };
            } else {
                window.onload = setup;
            }
        }
    })(function () {
        state.isOverIFrame = false;
        state.firstBlur = false;
        state.hasFocusAcquired = false;

        findIFramesAndBindListeners();

        document.body.addEventListener('click', onClick);

        if (typeof window.attachEvent !== 'undefined') {
            top.attachEvent('onblur', function () {
                state.firstBlur = true;
                state.hasFocusAcquired = false;
                onIFrameClick()
            });
            top.attachEvent('onfocus', function () {
                state.hasFocusAcquired = true;
                console.log('attachEvent.focus');
            });
        } else if (typeof window.addEventListener !== 'undefined') {
            top.addEventListener('blur', function () {
                state.firstBlur = true;
                state.hasFocusAcquired = false;
                onIFrameClick();
            }, false);
            top.addEventListener('focus', function () {
                state.hasFocusAcquired = true;
                console.log('addEventListener.focus');
            });
        }

        setInterval(findIFramesAndBindListeners, 500);
    });

    function isFF() {
        return navigator.userAgent.search(/firefox/i) !== -1;
    }

    function isActiveElementChanged() {
        const prevActiveTag = document.activeElement.tagName.toUpperCase();
        document.activeElement.blur();
        const currActiveTag = document.activeElement.tagName.toUpperCase();
        return !prevActiveTag.includes('BODY') && currActiveTag.includes('BODY');
    }

    function onMouseOut() {
        if (!state.firstBlur && isFF() && isActiveElementChanged()) {
            console.log('firefox first click');
            onClick();
        } else {
            document.activeElement.blur();
            top.focus();
        }
        state.isOverIFrame = false;
        console.log(`onMouseOut`);
    }

    function onMouseOver() {
        state.isOverIFrame = true;
        console.log(`onMouseOver`);
    }

    function onIFrameClick() {
        console.log(`onIFrameClick`);
        if (state.isOverIFrame) {
            onClick();
        }
    }

    function onClick() {
        console.log(`onClick`);
    }

    function findIFramesAndBindListeners() {
        return Array.from(document.getElementsByTagName('iframe'))
            .forEach(function (element) {
                element.onmouseover = onMouseOver;
                element.onmouseout = onMouseOut;
            });
    }
}

@aiglevn
Copy link

aiglevn commented Oct 19, 2018

Very Useful! Thanks!

@gwhitelaw
Copy link

Nice one @dawaltconley

@jtabone16
Copy link

Perfect!

@Taimoor-Tariq
Copy link

What if I have 4 iframes. I cant figure out how to separate them, when I click on one of them the function executes for all of them. My function is it zooms in the iframe when clicked but when i click 1 all of them get zoomed

@doughballs
Copy link

ANN0Y1NGHACKER, here's how I targeted a specific iframe for a google captcha:

var frames = Array.from(document.getElementsByTagName('iframe'));
var recaptchaWindow;

frames.forEach(function(x){
if (x.src.includes('google.com/recaptcha/api2/bframe') ){
recaptchaWindow = x.parentNode.parentNode;
};
});

@nahidhasankakon
Copy link

How to disable right click on iframe content.I have tried long time but can't solve it yet. I need this solution badly.Do u have any idea?

@kivervinicius
Copy link

kivervinicius commented Jul 15, 2019

JQuery version

        var iframeMouseOver = false;
	$("YOUR_CONTAINER_ID")
		.off("mouseover.iframe").on("mouseover.iframe", function() {
			iframeMouseOver = true;
		})
		.off("mouseout.iframe").on("mouseout.iframe", function() {
			iframeMouseOver = false;
		});

	$(window).off("blur.iframe").on("blur.iframe", function() {
		if(iframeMouseOver){
			$j("#os_top").click();
		}
	});

@yaquawa
Copy link

yaquawa commented Aug 9, 2019

Thanks! I created a script to simulate click event propagation of iframe.🥳

propagate_iframe_click_event.js

@ssoulless
Copy link

Could somebody provide an example to add mobile support?

@ssoulless
Copy link

I just created a bounty on StackOverflow for the one who tell me how to add mobile support to this code

@gusdewa
Copy link

gusdewa commented Jun 25, 2020

Thanks for this.

When we have cross-domain iframe, this will stop triggering the click on the iframe it self.
Any idea how to trigger both the parent blur event and the iframe click event?

@azu-kodix
Copy link

If page has multiple iframes then event will only fire the first time, unless you return focus to the page. Hmm..

@lewisMachilika
Copy link

This is so great. Thank you a lot.

@qiutian00
Copy link

so awsome !

@azharr-ansariii
Copy link

did anyone done it with mobile Device???

@dkornilove
Copy link

did anyone done it with mobile Device???

also working in FireFox. thanks to @dawaltconley

window.addEventListener('blur', function () {
                window.setTimeout(function () {
                    if (document.activeElement == document.querySelector('your_iframe_selector')) {
                        //handle click
                    }
                }, 0);
});

@gentle-media
Copy link

gentle-media commented Mar 23, 2023

As far as I can test this seems to work in Chrome and Firefox, but not in Safari. Anyone else got a workaround to get this working in Safari?

Also I would like to mention that if you add window.focus(); the user then don't have to click outside the iFrame themselves before it can register again a 'click' on the iFrame.

window.addEventListener('blur', function () {
    window.setTimeout(function () {
        if (document.activeElement == document.querySelector('your_iframe_selector')) {
            //handle click
            window.focus();
        }
    }, 0);
});

@gentle-media
Copy link

As far as I can test this seems to work in Chrome and Firefox, but not in Safari. Anyone else got a workaround to get this working in Safari?

Correction! It does work in (desktop) Safari. I needed to clear the browser history and after that my 'HTML/CSS/JS iframe click wizardry' did what it was supposed to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment