Reputation: 4772
I want a click handler that gets fired whenever the user clicks anything on the page. I don't need to know what they clicked on, just that they clicked. (See the note at the end for why I want this.)
Adding an event handler to the document.body works for most pages:
document.body.addEventListener("click", userActivityDetected);
The main thing that doesn't work is if the page has iframes inside it. These are iframes showing content from the same origin (I know that you can't detect anything in cross-origin iframes). If I add the event handlers to each iframe's contentDocument
element, I can get the behavior I want. The problem is, my code needs to be generic, so I don't know in advance whether, or how many, iframes a page will have, or even if iframes will be dynamically added after the page loads.
What I really want is a way to add an event listener that applies to the current page and all (same-origin) iframes inside of it. If that's not possible, I'd like a way to detect when an iframe element is added to the page so that I can add the event handler to it.
Why I want this behavior: I want to keep the user's session from timing out if they're "active" on the page. I'm taking clicks and key presses as "active" (I would also be fine with focus changes).
Upvotes: 0
Views: 286
Reputation: 4772
Per @RyanWilson's comment, the fallback solution of detecting when an iframe element is added, and then adding the click handler to it would look like:
function userClicked() {
console.log("user clicked");
}
function addClickHandler(iframe) {
iframe.contentWindow.addEventListener("click", userClicked);
}
// Listen to all the iframes that already exist
for (let iframe of document.getElementsByTagName('iframe')) {
addClickHandler(iframe);
}
// Watch for new iframes
var observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
for (let addedNode of mutation.addedNodes) {
if (addedNode.nodeName.toLowerCase() === 'iframe') {
addClickHandler(addedNode);
}
}
}
});
observer.observe(document.body, {childList: true, subtree: true});
Upvotes: 1