web-dev-qa-db-ja.com

iframe内のクリックイベントを検出する

私はTinyMCEのプラグインを書いていますが、iframe内のクリックイベントの検出に問題があります。

私の検索から、私はこれを思いついた:

Iframeを読み込んでいます:

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

Iframe内のHTML:

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

jQuery:

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

私が見た他の投稿は通常、異なるドメインで問題があります(これはそうではありません)。しかし、それでも、イベントは検出されません。

このようなことはできますか?

45
Philip G

私はこのようにして解決しました:

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

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

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

よくわかりませんが、ただ使用できるかもしれません

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

または、_<script>_タグをiframeに追加して(内部のコードにアクセスできる場合)、フレームでwindow.parent.DoSomething()をコードとともに使用できます

_function DoSomething() {
    // do something here
}
_

親の中。これらのいずれも機能しない場合は、_window.postMessage_を試してください。 これに関するいくつかの情報があります

5
cpdt

私はこれが古いことを知っていますが、IDがコードで一致しないのはchoose_picであり、1つはchoose_picsです:

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

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

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

私の場合、内部HTMLと外部HTMLに2つのjQueryがありました。内部イベントを添付する前に、4つのステップがありました。

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

トリックは、内部jQueryを使用してイベントをアタッチすることです。内部jQueryの取得方法に注目してください。

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

JQueryからオブジェクトモデルにバストする必要がありました。私の場合、他の回答の$('iframe').contents()アプローチは機能しませんでした。なぜなら、それは外側のjQueryにとどまるからです。 (ところで、contentDocumentを返します。)

1
Bob Stein

誰かに役立つ場合にだけ投稿してください。私にとって、次のコードは完璧に機能しました:

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

「FileFrame」はiframe id、「take_payment」はiframe内のボタンです。 iframe内のフォームは異なるドメインに投稿されるため、loadを使用すると、次のようなエラーメッセージが表示されます。

Origin " https://www.example.com "のフレームがOrigin " https://secure-test.worldpay.com "のフレームにアクセスするのをブロックしました。プロトコル、ドメイン、およびポートは一致する必要があります。

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

受け入れられた答えの「迅速で再現可能な」バージョンに興味がある人は、以下を参照してください。 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>
<body>
<a href="https://stackoverflow.com/">SOreadytohelp</a>
</body>
</html>
1

私の場合、親ドキュメントからカスタムイベントを発生させ、それを子iframeで受信しようとしていたため、次のことを行う必要がありました。

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

そして、iframeドキュメントで:

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