Tampermonkey получить таблицу в iframe?

Я пытаюсь улучшить графический интерфейс одного из наших инструментов, но у меня ничего не получается. Пользовательский интерфейс состоит из тела с несколькими iFrames, из которых я хочу выбрать один и немного изменить содержимое.

Проблема в том, что при использовании моего селектора frame = $("iframe[src*='/vs/virt.jsp']"); похоже, что он не может найти элемент.

Вот код (не делает ничего, кроме журнала):

// ==UserScript==
// @name UI Tweaks
// @version 0.2
// @description Does stuff
// @match https://*.local/vs/*
// @run-at          document-end
// @grant none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==


console.log(window.location);
console.log("before");
console.log($());
frame = $("iframe[src*='/vs/virt.jsp']");
console.log(frame.attr("id"));
console.log("after");

При запуске этого на странице я получаю две загрузки страницы, и он показывает объект местоположения до и после. Но объект фрейма совершенно пуст.

Однако при запуске того же самого в консоли разработчика Chrome после загрузки страницы я получаю искомые элементы.

Я пробовал разные способы загрузки скрипта только после загрузки страницы и т. Д., Но он все еще не работает.

Обновлять:

Я добавил:

// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js

Затем попробовал это:

waitForKeyElements (
    "iframe[src*='/vs/virt.jsp']",
    test()
);

function test(){
    frame = $("iframe[src*='/vs/virt.jsp']");
    console.log(frame.attr("id"));
}

Все тот же результат. Стоит отметить, что я использую Tampermonkey, но, возможно, это то же самое?

Редактировать 2:

function timer() {
  frame = $("iframe[src*='/vs/virt.jsp']");
    console.log(frame.attr("id"));
    setTimeout(timer, 1000);
}

timer();

Он продолжает выводить «undefined», тогда как, если я попробую это в консоли разработчика Chrome, я получу объект. Это как Tampermonkey не имеет доступа?


person PatrikJ    schedule 15.10.2015    source источник
comment
$("iframe[iframe[src*='/vs/virt.jsp']"); это опечатка в вопросе, верно, это не настоящий код?   -  person Jaromanda X    schedule 15.10.2015
comment
Это опечатка. Исправляем сейчас. Спасибо за наблюдение!   -  person PatrikJ    schedule 15.10.2015
comment
Элемент iframe, вероятно, будет создан позже. Попробуйте использовать waitForKeyElements или MutationObserver.   -  person wOxxOm    schedule 15.10.2015
comment
Сделаю и отчитаюсь   -  person PatrikJ    schedule 16.10.2015
comment
Пробовал ждатьForKeyElements. MutationObserver выглядит выше моего уровня навыков. :)   -  person PatrikJ    schedule 16.10.2015
comment
@PatrikJ, test() в вашем новом коде — это не обратный вызов, а немедленный вызов функции вызов. Удалите (). Кроме того, с @grant none скрипт запускается в контексте веб-страницы, поэтому у вас могут быть две конфликтующие библиотеки jQuery, если веб-страница использует свою собственную. Удалить @grant none. И переработайте код, чтобы использовать @grant unsafeWindow, но только при необходимости.   -  person wOxxOm    schedule 16.10.2015


Ответы (1)


Поскольку ваш iFrame находится в том же домене, что и ваша главная страница, довольно просто настроить таргетинг на изменения iframe с помощью waitForKeyElements(). Он был разработан с учетом такой возможности.
Передайте действительный селектор iFrame в качестве 4-го параметра.

Например:

  1. Перейдите на эту страницу jsFiddle. Он динамически создает iframe с идентификатором tstIframe и выглядит так:

    Исходное состояние

  2. Когда вы нажимаете кнопку, она добавляет строку текста в iframe — в div с классом comment.

  3. Предположим, мы хотим обработать этот текст, тогда этот скрипт сделает это:

    // ==UserScript==
    // @name        Dynamic iframe content manipulator
    // @match       http://fiddle.jshell.net/5zqfthx7/*
    // @require     http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
    // @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant       GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    waitForKeyElements (
        ".comment",
        styleComment,
        false,
        "#tstIframe"
    );
    
    function styleComment (jNode) {
        jNode.css ("background", "lime");
    }
    
  4. Когда вы установите этот скрипт, перезагрузите страницу и нажмете кнопку, вы увидите, что каждая новая строка становится окрашенной, например:

    Скрипт в действии


Примечания:

  1. Не используйте @noframes в этом случае. Tampermonkey не применяет его должным образом в такого рода манипуляциях с iframe, особенно если iframe не имеет src.
  2. При использовании @require всегда используйте @grant, отличный от none, если вы не знаете точно, как JS страницы и скрипт будут взаимодействовать и конфликтовать.
  3. Дополнительные параметры доступны в Firefox. Chrome по-прежнему имеет привередливую/ограниченную поддержку iframe.
  4. Наконец, поскольку у вашего iFrame есть src, часто вы можете просто написать для него сценарий, как если бы это была единственная страница. Настройте свои директивы @match и т. д., чтобы они срабатывали на iframe, и, возможно, оберните код в структура if (self !== top) {... }.
    См., например, этот ответ.
person Brock Adams    schedule 28.11.2015