Skip to content

Instantly share code, notes, and snippets.

@micdenny
Last active May 29, 2024 07:58
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);
}
}
}
@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