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;
});
@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