-
-
Save micdenny/db03a814eaf4cd8abf95f77885d9316f to your computer and use it in GitHub Desktop.
<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); | |
} | |
} | |
} |
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.
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.
Okay. But can you provide some help about how can we track/capture multiple events? Thank you!
Hi @micdenny
Do you have a unit test spec file for this iframe-tracker.directive.ts? If yes can you please share them ?
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.
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
Any idea on how to make this work with touch devices as well?
I triedtouchstart
andtouchend
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
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.
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 ??
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.