Привязать событие клика к классу внутри iframe

Я работал над этим последние несколько дней и чувствую, что близок, но что-то упускаю. То, что я пытаюсь сделать, это отобразить модальное всплывающее окно, когда пользователь выбирает язык из виджета Google Translate.

Поскольку языки, которые могут выбирать пользователи, находятся внутри iframe, добавленного виджетом javascript после загрузки dom, я использую setInterval для проверки доступности iframe (по какой-то причине функция jquery .load() никогда не будет работать для меня). У меня также есть другой метод setInterval для проверки загрузки языковых классов (они не доступны сразу, когда доступен iframe).

Когда я привязываю событие щелчка к языковым элементам, все работает так, как ожидалось... один раз... для любого элемента, на который нажали. Если я уберу clearInterval(waitForLanguageLinks), то все будет работать как положено каждый раз, но это вызовет утечку памяти и страница в конце концов вылетит (как и следовало ожидать).

Итак, мой вопрос: как я могу привязать событие щелчка к каждому из этих элементов внутри обратного вызова setInterval() и оставить это событие связанным после вызова clearInterval() (надеюсь, это имеет смысл).

$(document).ready(function(){

    var iframe;
    var languageElements;

    var translateIframeCheck = setInterval(function(){

        iframe = $('.goog-te-menu-frame').contents();

        if(iframe.length > 0){

            clearInterval(translateIframeCheck);

        }

    }, 100);

    var waitForLanguageLinks = setInterval(function(){

        languageElements = iframe.find('.goog-te-menu2-item');

        if(typeof iframe !== "undefined" && languageElements.length > 0){

            languageElements.click(function(){

                console.log($(this).find('.text').html());

            });

            clearInterval(waitForLanguageLinks);

        }

    }, 100);    

});

iframe, загруженный скриптом Google для перевода:

<iframe class="goog-te-menu-frame skiptranslate" title="Language Translate Widget" style="visibility: visible; box-sizing: content-box; width: 1004px; height: 285px; left: 413.5px; top: 167px;" frameborder="0"></iframe>

person whitwhoa    schedule 21.02.2018    source источник
comment
iframe загружается динамически скриптом Google. Обновили вопрос, чтобы показать iframe. Атрибут src отсутствует.   -  person whitwhoa    schedule 22.02.2018
comment
Сладко, так что вы должны быть хороши в том, что касается XSS, :)   -  person Taplar    schedule 22.02.2018
comment
Итак, когда вы щелкаете один из элементов в iframe, вызывает ли это переход iframe? Или внутри него есть скрипт, который просто подменяет содержимое тела? Если он делает последнее, вы потенциально можете делегировать привязку к телу iframe, и тогда независимо от того, заменяется ли содержимое тела, эти привязки будут существовать.   -  person Taplar    schedule 22.02.2018
comment
Содержимое iframe представляет собой несколько таблиц, содержащих теги привязки с классом .goog-te-menu2-item. HTML-код каждого из этих тегов привязки соответствует языку, который выбирает пользователь. Содержимое самого iframe не меняется. Когда пользователь щелкает одну из этих ссылок, Google переводит содержимое родительского элемента iframe, т. е. веб-страницы.   -  person whitwhoa    schedule 22.02.2018
comment
Хорошо, тогда попробуйте изменить свои привязки, чтобы они были делегированными привязками событий. Ссылка learn.jquery.com/events/event-delegation   -  person Taplar    schedule 22.02.2018


Ответы (1)


Согласно предложению @Taplar, использование делегировать привязки событий решило эту проблему. Следующий код демонстрирует, как получить выбранный язык из раскрывающегося списка Google Translate и войти в консоль. Это должно стать хорошей отправной точкой для всех, кто столкнется с этим вопросом в будущем.

<!-- BEGIN GOOGLE TRANSLATE
---------------------------------------------------------------------->

<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<div id="google_translate_element"></div>
<script type="text/javascript">     
function googleTranslateElementInit() {
    new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false}, 'google_translate_element');
}
</script>

<script>
/*
    Keep in mind:
        > If google ever changes the structure of the translate element, this code
            will no longer function, and will have to be updated to reflect those
            changes.
        > There appears to be a bug in the translation widget itself where if
            a langauge other than the default langauge is chosen and the page is
            translated, then the default language is chosen again, then another
            langauge is chosen, nothing will happen, and the language must be
            selected a second time. 
*/


$(document).ready(function(){

    var iframe;

    var translateIframeCheck = setInterval(function(){

        iframe = $('.goog-te-menu-frame').contents();

        if(iframe.length > 0){


            $(iframe).on("click", ".goog-te-menu2 table tbody tr td a", function(){

                console.log($(this).find('.text').html());

            });

            clearInterval(translateIframeCheck);

        }

    }, 100);


});


</script>
<!----------------------------------------------------------------------
END GOOGLE TRANSLATE -->
person whitwhoa    schedule 22.02.2018