Skip to content

Instantly share code, notes, and snippets.

@micdenny
Last active October 17, 2024 11:05
Show Gist options
  • Save micdenny/db03a814eaf4cd8abf95f77885d9316f to your computer and use it in GitHub Desktop.
Save micdenny/db03a814eaf4cd8abf95f77885d9316f to your computer and use it in GitHub Desktop.
How to detect a click event on a cross domain iframe (iframe.tracker)
<div>
<iframe appIframeTracker (iframeClick)="onIframeClick()" src="http://www.google.com"></iframe>
</div>
import {
Directive,
ElementRef,
OnInit,
Renderer2,
Input,
Output,
EventEmitter,
HostListener
} from '@angular/core';
@Directive({
selector: '[appIframeTracker]'
})
export class IframeTrackerDirective implements OnInit {
private iframeMouseOver: boolean;
@Input() debug: boolean;
@Output() iframeClick = new EventEmitter<ElementRef>();
constructor(private el: ElementRef, private renderer: Renderer2) {}
ngOnInit(): void {
this.renderer.listen(window, 'blur', () => this.onWindowBlur());
}
@HostListener('mouseover')
private onIframeMouseOver() {
this.log('Iframe mouse over');
this.iframeMouseOver = true;
this.resetFocusOnWindow();
}
@HostListener('mouseout')
private onIframeMouseOut() {
this.log('Iframe mouse out');
this.iframeMouseOver = false;
this.resetFocusOnWindow();
}
private onWindowBlur() {
if (this.iframeMouseOver) {
this.log('WOW! Iframe click!!!');
this.resetFocusOnWindow();
this.iframeClick.emit(this.el);
}
}
private resetFocusOnWindow() {
setTimeout(() => {
this.log('reset focus to window');
window.focus();
}, 100);
}
private log(message: string) {
if (this.debug) {
console.log(message);
}
}
}
@santoshprakash
Copy link

how to track if any button clicked inside an iframe?

@micdenny
Copy link
Author

micdenny commented May 1, 2020

This was just meant to track the click on the iframe itself, you can’t intercept click inside the iframe nor on the iframe itself. If you own the content on the iframe you should use postMessage to communicate cross window (remember that an iframe is a complete window instance). In fact this script is using the trick to check if the current window has lost the focus, and the mouse was inside the iframe boundaries that is the only thing you can know about it.

@muneebriaz
Copy link

I tried this and it works fine. but how can we detect multiple clicks?
It resets after the first click and doesn't even allow you to enter inputs in fields.

@micdenny
Copy link
Author

micdenny commented Jul 4, 2020

It can only detect the first click, because it’s using the trick of the window lost focus + iframe boundaries, the use case for me was to “zoom” the iframe when the user clicks on it, taking the iframe container and move on a bigger container to zoom the iframe.

@muneebriaz
Copy link

Okay. But can you provide some help about how can we track/capture multiple events? Thank you!

@micdenny
Copy link
Author

micdenny commented Jul 6, 2020 via email

@vikistunner1987
Copy link

vikistunner1987 commented Jun 1, 2023

Hi @micdenny

Do you have a unit test spec file for this iframe-tracker.directive.ts? If yes can you please share them ?

@jachwe
Copy link

jachwe commented Feb 2, 2024

This is great, exactly what i need.
Any idea on how to make this work with touch devices as well?
I tried touchstart and touchend without success.

My use case is a logout timer, which i need to reset on every interaction.
But in one specific case this interaction is inside an iframe.

@micdenny
Copy link
Author

micdenny commented Feb 2, 2024

Do you have a unit test spec file for this iframe-tracker.directive.ts? If yes can you please share them ?

no, I don't have, sorry

@micdenny
Copy link
Author

micdenny commented Feb 2, 2024

Any idea on how to make this work with touch devices as well?
I tried touchstart and touchend without success.

I never thought about it, sorry

My use case is a logout timer, which i need to reset on every interaction.
But in one specific case this interaction is inside an iframe.

as I said above, you can't really intercept interaction inside the iframe, when the user click on the iframe the user is in a completely different windows that is a sandbox and it is strictly limited what you can do: https://www.w3docs.com/learn-javascript/cross-window-communication.html

@jachwe
Copy link

jachwe commented Feb 3, 2024

Thanks for the swift reply.
I understand that i cannot intercept the interaction inside the iframe. That's also not what i need. All i need to know is that there is any interaction. Just like your script does. But i would also need it for touch devices and not only desktop. But nevermind. Maybe that is not the way to go for me.

@jbelda
Copy link

jbelda commented Mar 25, 2024

But what if i need type something inside the iframe?? it's imposible because always lose the focus on the textarea inside the iframe. Am i right ??

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