简体   繁体   English

向文档中的所有帧添加事件侦听器

[英]To add event listeners to all the frames in a document

I am working on something which requires me to add mouse/keyboard event listeners to the document on document load. 我正在研究一些需要我在文档加载时将鼠标/键盘事件监听器添加到文档的东西。

document/window.addEventListener() worked well until I came across Frameset/frames/iframes. document/window.addEventListener()运行良好,直到我遇到Frameset / frames / iframes。

I did some workaround, like iterating through all the frames of frameset and added event-listeners to them. 我做了一些解决方法,比如迭代框架集的所有框架并向它们添加事件监听器。

Then I realized frames are loaded dynamically, after DOM. 然后我意识到在DOM之后动态加载帧。 So I've done something like this: 所以我做了这样的事情:

    bindListenersToFrame: function(element){
        var $ = domUtils.jQuery;
        $(element).ready(function(){
            if(element.tagName == "FRAMESET" || element.tagName == "BODY"){
                    for(var i=0; i < element.children.length; i++){
                            domUtils.bindListenersToFrame(element.children[i]);
                    }
            }
            if(element.tagName == "FRAME" || element.tagName == "IFRAME"){
                $('iframe').load(function(){
                    domUtils.addListener(element);
                    if(element.contentDocument.documentElement){
                            for(var i=0; i < element.contentDocument.documentElement.children.length; i++){
                                    domUtils.bindListenersToFrame(element.contentDocument.documentElement.children[i]);
                            }
                    }
                });
            }
        });
}

Above method is recursive in nature and domUtils is just a object with methods like "addListener". 上面的方法本质上是递归的,而domUtils只是一个像“addListener”这样的方法的对象。

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thank you. 谢谢。

Why not add the listener to <body> ? 为什么不将监听器添加到<body>

$('body').click(function(e) {
    console.log("clicked")
})

Try this: 尝试这个:

$('body').on('click','iframe',function(e) {
       console.log("clicked");
});

I would suggest recursively checking for frames and attaching listeners. 我建议递归检查帧并附加监听器。 This really shouldn't be done, but it's the only way. 这真的不应该做,但这是唯一的方法。 Be aware this snippet does not work on SO due to sandboxing restrictions on snippets. 请注意,由于对代码段的沙盒限制,此代码段无法在SO上运行。 I have tested it and it works locally an a server. 我测试了它,它在本地工作的服务器。 I am also not able to find (in the limited time I have) a way around the setTimeout I am currently using. 我也无法找到(在有限的时间内)我正在使用的setTimeout方法。 It feels like it gets applied before the page is loaded, but I can't see any effect from these load events, so for the sake of just showing how it could work, please check this: 感觉它在页面加载之前被应用,但我看不到这些load事件的任何影响,所以为了显示它是如何工作的,请检查:

 function nestedIFrameEventAttacher( iframe, event, handler ){ const content = iframe.contentDocument || (iframe.contentWindow ? iframe.contentWindow .document : iframe); const body = content.querySelector( 'body' ); body.addEventListener( event, handler ); // I have tried attaching `load` and `DOMContentLoaded` events // to the `iframe` and the `body` but none of them seemed to trigger. // This is therefor not guaranteed to work, but you can start from this. setTimeout(function(){ Array.from( body.querySelectorAll( 'iframe' ) ).forEach(iframe => { nestedIFrameEventAttacher( iframe, event, handler ); }); }, 100); } const output = document.getElementById( 'output' ) nestedIFrameEventAttacher( document, 'click', function( event ){ output.textContent = this.querySelector( 'h1' ).textContent; }); 
 #output{ color: red; } 
 <div id="output">Stealie the Dog</div> <h1>Root</h1> <iframe srcdoc="<html><head></head><body><h1>Second</h1><iframe srcdoc='<html><head></head><body><h1>Deeper</h2></body></html>'></iframe></body></html>" width="100%" height="500px"></iframe> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM