it-swarm.com.ru

Обнаружить событие клика внутри iframe

Я пишу плагин для TinyMCE, и у меня возникла проблема с обнаружением событий нажатия внутри iframe. 

Из моего поиска я пришел к этому:

Загрузка iframe:

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

HTML внутри iframe:

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

jQuery:

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

Другие сообщения, которые я видел, обычно имеют проблемы с другими доменами (это не имеет). Но, тем не менее, событие не обнаружено. 

Можно ли что-то подобное сделать?

40
Philip G

Я решил это, сделав так:

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

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

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

Я не уверен, но вы можете просто использовать

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

Либо так, либо вы можете просто добавить тег <script> в iframe (если у вас есть доступ к коду внутри), а затем использовать window.parent.DoSomething() во фрейме с кодом

function DoSomething() {
    // do something here
}

в родительском .. Если ничего из этого не работает, попробуйте window.postMessage. Вот некоторая информация об этом .

5
cpdt

Я знаю, что это старый, но идентификаторы не совпадают в вашем коде, один - choose_pic и один - choose_pics :

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

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

API tinymce заботится о многих событиях в редакторах 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

В моем случае было два jQuery's , для внутреннего и внешнего HTML. У меня было четыре шага, прежде чем я смог прикрепить внутренние события:

  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, а take_payment - кнопка внутри iframe. Поскольку моя форма внутри iframe размещается в другом домене, при использовании load я получил сообщение об ошибке:

Заблокирован фрейм с источником " https://www.example.com " от доступа к фрейму с источником " https://secure-test.worldpay.com ". Протоколы, домены и порты должны совпадать.

1
Abhijith
$("#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
BigDataScientist

В моем случае я пытался запустить пользовательское событие из родительского документа и получить его в дочернем 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