Вызов функции во фрейме с использованием скрипта Greasemonkey - PullRequest
3 голосов
/ 10 января 2012

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

В любом случае, экран для регистрации звонков состоит из нескольких кадров, только один из них представляет интерес для меня с точки зрения автоматизации. Выделенный HTML-код для страницы и фрейма (включая элемент, который я пытаюсь редактировать) выглядят следующим образом:

<html>
<head>
</head>
<frameset framespacing="0" border="0" bordercolor="#ffffff" rows="130,*,22,0">
    <frame scrolling="no" marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" noresize="" src="top.asp?menu=&page=" name="menu">
    </frame>
    <frameset id="contentCols" framespacing="8" border="8" cols="250, *" bordercolor="#ffffff">

        <frame marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" border="0" src="../service/loading.html" name="content" frameborder="0" style="padding-right: 10px;">
            <html>
            <head>
            </head>
            <body class="winBack" style="background-color: rgb(255, 255, 255);">

            <div id="scrollableContainer" class="lockedTableContainer scrollableContainerHeight" style="position: relative; height: 0px;">

            <table cellspacing="1" cellpadding="3" border="0">
            <form id="configFields" name="configFields" method="post" action="/ics/tt/ticketNew.asp"></form>
                <input type="hidden" value="" name="task">
                <input type="hidden" value="account" name="source">
                <tbody>
                <tr id="ROW_109094">
                    <td class="webCaption" style="width: 160px;">
                    </td>

                    <td class="formText">
                        <select id="FIELD_109094_DROPDOWN_null" class="formText" style="width: 200px;" title="Establishment Type" name="FIELD_109094_DROPDOWN_null" onchange="updateDep(109094, this.options[this.selectedIndex].value);">
                        </select>
                    </td>
                </tr>
                </tbody>
            <table>
            </div>
        </frame>
    </frameset>
</frameset>
</html>


Я пытаюсь установить selectedIndex элемента FIELD_109094_DROPDOWN_null select.
Затем я пытаюсь запустить функцию updateDep (которая содержится в скрипте, прикрепленном к фрейму), который присоединен к событию изменения элемента; эта функция показывает некоторые другие поля в зависимости от значения, установленного в данный момент в элементе select.

Используя консоль Firebug, я могу добиться этого, используя следующие две строки:

frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2;
frames["content"].updateDep(109094, frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").options[2].value);

Однако, когда я помещаю это в скрипт Greasemonkey и присоединяю его либо к загрузке основного окна, либо к загрузке фрейма; Я получаю эту ошибку:

Ошибка: frames.content.document.getElementById ("FIELD_109094_DROPDOWN_null") равен нулю

Однако, если я использую следующий код, я могу по крайней мере изменить выбранный индекс выбранного элемента:

document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2;

Я не могу понять, как запустить функцию updateDep через скрипт Greasemonkey. Код в скрипте выглядит следующим образом:

// ==/UserScript==

var initElements = (function () {

    var elementExists = document.getElementById("FIELD_109094_DROPDOWN_null");

    if(elementExists)
    {
        document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2;
        frames["content"].updateDep(109094, frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").options[2].value);

    }
}
)();

window.addEventListener('load', initElements, false);

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 11 января 2012

Хитрость с фреймами и iFrames заключается в том, что каждый из них выглядит как отдельная страница для Greasemonkey.

Таким образом, для рассматриваемого HTML-кода сценарий GM может в конечном итоге выполняться 3 раза, в зависимости от того, как были настроены директивы @include, @exclude и / или @match.

Таким образом, один и тот же элемент будет отображаться по-разному (или не отображаться вообще) в зависимости от того, через какой цикл выполняется скрипт. Поэтому не используйте код, подобный frames["content"], если вы точно не знаете / не контролируете состояние выполнения скрипта. Лучше проверять узлы и выполнять код условно.

Другое дело, что при использовании JavaScript, который находится на целевой странице, вам нужно использовать unsafeWindow или обходной путь.

Собирая все вместе, код вроде так должен работать:

var depSelect   = document.querySelector ("#FIELD_109094_DROPDOWN_null");
if (depSelect) {
    depSelect.selectedIndex = 2;
    unsafeWindow.updateDep (109094, depSelect.options[2].value);
}

(при условии, что с директивами @include, @exclude и / или @match нет ничего смешного.)

Вам не нужно ни window.addEventListener('load'..., ни заключать код в initElements().

0 голосов
/ 21 декабря 2017

Я обнаружил, что GM не распознает кадры по имени.Единственный способ заставить мой скрипт работать, это использовать фрейм index вместо имени.

 frames[2].document...

вместо

 frames['aname'].document...
...