it-swarm.com.de

Klickereignis im iframe erkennen

Ich schreibe ein Plugin für TinyMCE und habe ein Problem mit dem Erkennen von Klickereignissen in einem Iframe. 

Von meiner Suche habe ich folgendes gefunden:

Iframe wird geladen:

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

HTML in iframe:

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

jQuery:

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

Andere Posts, die ich gesehen habe, haben normalerweise ein Problem mit anderen Domains (dies hat nicht der Fall). Dennoch wird das Ereignis nicht erkannt. 

Kann so etwas gemacht werden?

40
Philip G

Ich habe es so gelöst:

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

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

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

Ich bin mir nicht sicher, aber Sie können vielleicht einfach verwenden

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

Entweder das oder Sie können einfach ein <script>-Tag in den iframe einfügen (wenn Sie Zugriff auf den Code haben) und dann window.parent.DoSomething() im Frame mit dem Code verwenden

function DoSomething() {
    // do something here
}

im übergeordneten Element Wenn dies nicht zutrifft, versuchen Sie es mit window.postMessage. Hier sind einige Informationen dazu .

5
cpdt

Ich weiß, das ist alt, aber die IDs stimmen in Ihrem Code nicht überein, eine ist select_pic und eine ist select_pics:

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

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

Die tinymce-API kümmert sich um viele Ereignisse im iframe der Editoren. Ich empfehle dringend, sie zu verwenden. Hier ist ein Beispiel für den Click-Handler

// 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

In meinem Fall gab es zwei jQuery's , für den inneren und äußeren HTML-Code. Ich hatte vier Schritte, bevor ich innere Ereignisse hinzufügen konnte:

  1. warten Sie, bis die äußere jQuery fertig ist 
  2. warten Sie, bis der iframe geladen ist 
  3. innere jQuery greifen
  4. warten Sie, bis die innere jQuery fertig ist

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

Der Trick besteht darin, die innere jQuery zum Anhängen von Ereignissen zu verwenden. Beachten Sie, wie ich die innere jQuery bekomme:

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

Ich musste dafür aus jQuery in das Objektmodell springen. Der $('iframe').contents()-Ansatz in den anderen Antworten hat in meinem Fall nicht funktioniert, da dies bei der äußeren jQuery bleibt. (Und übrigens gibt contentDocument zurück.)

1
Bob Stein

Einfach posten, falls es jemandem hilft. Für mich hat der folgende Code perfekt funktioniert:

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

Dabei ist 'FileFrame' die Iframe-ID und 'take_payment' die Schaltfläche in Iframe. Da mein Formular im iframe in einer anderen Domäne veröffentlicht wird, wurde beim Laden eine Fehlermeldung angezeigt:

Blockierte einen Frame mit Origin " https://www.example.com " durch den Zugriff auf einen Frame mit Origin " https://secure-test.worldpay.com " Protokolle, Domänen und Ports müssen übereinstimmen.

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

Wenn sich jemand für eine "schnell reproduzierbare" Version der akzeptierten Antwort interessiert, siehe unten. Kredite an einen Freund, der nicht bei SO ist. Diese Antwort kann auch in die akzeptierte Antwort mit einer Bearbeitung, ....__, integriert werden.

<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

In meinem Fall habe ich versucht, ein benutzerdefiniertes Ereignis aus dem übergeordneten Dokument auszulösen und es im untergeordneten iframe zu empfangen. Daher musste ich Folgendes tun:

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

und im iframe-Dokument:

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