Javascript 检测 iframe 内的点击事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13439303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:06:25  来源:igfitidea点击:

Detect click event inside iframe

javascriptjqueryhtmliframetinymce

提问by Philip G

I'm writing a plugin for TinyMCE and have a problem with detecting click events inside an iframe.

我正在为 TinyMCE 编写一个插件,但在检测 iframe 内的点击事件时遇到了问题。

From my search I've come up with this:

从我的搜索中,我想出了这个:

Loading iframe:

加载 iframe:

<iframe src='resource/file.php?mode=tinymce' id='filecontainer'></iframe>

HTML inside iframe:

iframe 内的 HTML:

<input type=button id=choose_pics value='Choose'>

jQuery:

jQuery:

//Detect click
$("#filecontainer").contents().find("#choose_pic").click(function(){
    //do something      
}); 

Other posts I've seen usually have a problem with different domains (this hasn't). But, still, the event isn't detected.

我见过的其他帖子通常在不同的域中都有问题(这没有)。但是,仍然没有检测到该事件。

Can something like this be done?

可以做这样的事情吗?

回答by Philip G

I solved it by doing like this:

我通过这样做解决了它:

$('#filecontainer').load(function(){

        var iframe = $('#filecontainer').contents();

        iframe.find("#choose_pics").click(function(){
               alert("test");
        });
});

回答by cpdt

I'm not sure, but you may be able to just use

我不确定,但你可以使用

$("#filecontainer #choose_pic").click(function() {
    // do something here
});

Either that or you could just add a <script>tag into the iframe (if you have access to the code inside), and then use window.parent.DoSomething()in the frame, with the code

或者你可以<script>在 iframe 中添加一个标签(如果你可以访问里面的代码),然后window.parent.DoSomething()在框架中使用代码

function DoSomething() {
    // do something here
}

in the parent. If none of those work, try window.postMessage. Here is some info on that.

在父级。如果这些都不起作用,请尝试window.postMessage. 这里有一些关于这方面的信息

回答by KiwisTasteGood

I know this is old but the ID's don't match in your code one is choose_picand one is choose_pics:

我知道这是旧的,但代码中的 ID 不匹配,一个是choose_pic一个是choose_pics

<input type=button id=choose_pics value='Choose'>

$("#filecontainer").contents().find("#choose_pic").click(function(){
    //do something      
}); 

回答by Akash gupta

$("#iframe-id").load( function() {
    $("#iframe-id").contents().on("click", ".child-node", function() {
        //do something
    });
});

回答by Thariama

The tinymce API takes care of many events in the editors iframe. I strongly suggest to use them. Here is an example for the click handler

tinymce API 负责处理编辑器 iframe 中的许多事件。我强烈建议使用它们。这是单击处理程序的示例

// Adds an observer to the onclick event using tinyMCE.init
tinyMCE.init({
   ...
   setup : function(ed) {
      ed.onClick.add(function(ed, e) {
           console.debug('Iframe clicked:' + e.target);
      });
   }
});

回答by Abhijith Sasikumar

Just posting in case it helps someone. For me, the following code worked perfect:

只是张贴以防它对某人有帮助。对我来说,下面的代码很完美:

$(document).ready(function(){
     $("#payment_status_div").hide();
     var iframe = $('#FileFrame').contents();
     iframe.find("#take_payment").click(function(){
         $("#payment_status_div").show("slow");
     });
});

Where 'FileFrame' is the iframe id and 'take_payment' is the button inside iframe. Since my form inside the iframe is posted to a different domain, when used load, I got an error message saying:

其中“FileFrame”是 iframe id,“take_payment”是 iframe 内的按钮。由于我在 iframe 中的表单被发布到不同的域,因此在使用加载时,我收到一条错误消息:

Blocked a frame with origin "https://www.example.com" from accessing a frame with origin "https://secure-test.worldpay.com". Protocols, domains, and ports must match.

封闭原点“的帧https://www.example.com访问的帧与原籍”“ https://secure-test.worldpay.com”。协议、域和端口必须匹配。

回答by Bob Stein

In my case there were two jQuery's, for the inner and outer HTML. I had four steps before I could attach inner events:

就我而言,内部和外部 HTML有两个 jQuery。在附加内部事件之前,我有四个步骤:

  1. wait for outer jQuery to be ready
  2. wait for iframe to load
  3. grab inner jQuery
  4. wait for inner jQuery to be ready
  1. 等待外部 jQuery 准备就绪
  2. 等待 iframe 加载
  3. 获取内部 jQuery
  4. 等待内部 jQuery 准备好


$(function() {   // 1. wait for the outer jQuery to be ready, aka $(document).ready
    $('iframe#filecontainer').on('load', function() {   // 2. wait for the iframe to load
        var $inner$ = $(this)[0].contentWindow.$;   // 3. get hold of the inner jQuery
        $inner$(function() {   // 4. wait for the inner jQuery to be ready
            $inner$.on('click', function () {   // Now I can intercept inner events.
                // do something
            });
        });
    });
});

The trick is to use the inner jQuery to attach events. Notice how I'm getting the inner jQuery:

诀窍是使用内部 jQuery 来附加事件。注意我是如何获得内部 jQuery 的:

        var $inner$ = $(this)[0].contentWindow.$;

I had to bust out of jQuery into the object model for it. The $('iframe').contents()approach in the other answers didn't work in my case because that stays with the outer jQuery. (And by the way returns contentDocument.)

我不得不将 jQuery 用于它的对象模型。$('iframe').contents()其他答案中的方法在我的情况下不起作用,因为它与外部 jQuery 保持一致。(顺便说一下返回contentDocument。)

回答by Tonio Liebrand

If anyone is interested in a "quick reproducible" version of the accepted answer, see below. Credits to a friend who is not on SO. This answer can also be integrated in the accepted answer with an edit,... (It has to run on a (local) server).

如果有人对已接受答案的“快速可复制”版本感兴趣,请参见下文。归功于不在 SO 上的朋友。这个答案也可以通过编辑整合到接受的答案中,......(它必须在(本地)服务器上运行)。

<html>
<head>
<title>SO</title>
<meta charset="utf-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<style type="text/css">
html,
body,
#filecontainer {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<iframe src="http://localhost/tmp/fileWithLink.html" id="filecontainer"></iframe>

<script type="text/javascript">
$('#filecontainer').load(function(){

  var iframe = $('#filecontainer').contents();

  iframe.find("a").click(function(){
    var test = $(this);
    alert(test.html());
  });
});
</script>
</body>
</html>

fileWithLink.html

文件链接.html

<html>
<body>
<a href="https://stackoverflow.com/">SOreadytohelp</a>
</body>
</html>

回答by stevenlacerda

In my case, I was trying to fire a custom event from the parent document, and receive it in the child iframe, so I had to do the following:

就我而言,我试图从父文档触发自定义事件,并在子 iframe 中接收它,因此我必须执行以下操作:

var event = new CustomEvent('marker-metrics', {
    detail: // extra payload data here
});
var iframe = document.getElementsByTagName('iframe');
iframe[0].contentDocument.dispatchEvent(event)

and in the iframe document:

并在 iframe 文档中:

document.addEventListener('marker-metrics', (e) => {
  console.log('@@@@@', e.detail);
});