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
Detect click event inside iframe
提问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。在附加内部事件之前,我有四个步骤:
- wait for outer jQuery to be ready
- wait for iframe to load
- grab inner jQuery
- wait for inner jQuery to be ready
- 等待外部 jQuery 准备就绪
- 等待 iframe 加载
- 获取内部 jQuery
- 等待内部 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);
});

