【问题标题】:Detect click or focus events anywhere on page, including same-origin iframes检测页面上任意位置的点击或焦点事件,包括同源 iframe
【发布时间】:2018-05-02 17:47:18
【问题描述】:

我想要一个在用户点击页面上的任何内容时触发的点击处理程序。我不需要知道他们点击了什么,只知道他们点击了。 (为什么我想要这个,请参阅最后的注释。)

向 document.body 添加事件处理程序适用于大多数页面:

document.body.addEventListener("click", userActivityDetected);

主要的问题是页面内部是否有 iframe。这些是显示来自同一来源的内容的 iframe(我知道您无法在跨域 iframe 中检测到任何内容)。如果我将事件处理程序添加到每个 iframe 的 contentDocument 元素,我可以获得我想要的行为。问题是,我的代码需要是通用的,所以我事先不知道一个页面是否或有多少 iframe,或者即使 iframe 会在页面加载后动态添加。

我真正想要的是一种添加事件侦听器的方法,该侦听器适用于当前页面和其中的所有(同源)iframe。如果这不可能,我想要一种方法来检测何时将 iframe 元素添加到页面,以便我可以向其中添加事件处理程序。

为什么我想要这种行为:如果用户在页面上处于“活动状态”,我想防止他们的会话超时。我将点击和按键视为“活动”(我也可以更改焦点)。

【问题讨论】:

  • 你可以使用 document.getElementsByTagName('iframe'),然后迭代它们并添加你的点击事件监听器
  • @RyanWilson 这在开始时会起作用,但如果在页面加载后动态添加 iframe 元素则无济于事。
  • @TomPanning 您可以再添加一个getElementsByTagName('iframe'),只要在页面上添加元素,它就会迭代。
  • @TomPanning 基于 AndrewL 的评论,这篇 SO 帖子描述了如何设置 DOM 更改事件 (stackoverflow.com/questions/3219758/detect-changes-in-the-dom)
  • 您也可以使用事件委托,并且可能以 window 对象而不是 document.body 为目标

标签: javascript iframe


【解决方案1】:

根据@RyanWilson 的评论,检测何时添加 iframe 元素,然后向其添加点击处理程序的后备解决方案如下所示:

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

【讨论】:

    猜你喜欢
    • 2017-08-31
    • 2011-11-08
    • 1970-01-01
    • 2012-11-06
    • 2013-08-12
    • 2014-10-19
    • 2021-11-07
    • 2020-10-05
    • 1970-01-01
    相关资源
    最近更新 更多