エンジニアブログ

エンジニアブログ

Greasemonkey ユーザースクリプトの作成でハマったところ

ぴろり上西 2011年03月09日

 先日、Redmine 用の Greasemokey スクリプトを公開したのですが、まぁ、久々に JavaScript を書いたこともあって、幾つかハマりました。これといった検索結果にもヒットしなかったので、自分用まとめとしてメモしておきます。

form エレメントの submit イベントをフックしたい

 フォームの送信前に、フォームの入力データをチェックするとします。普通なら、getElementById か何かで目的の form エレメントを取得して、onsubmit に任意の関数を設定すればOKな感じですよね。これが動きません。エレメントは取得できているのですが、onsubmit に設定した関数が呼ばれません。issue_form1 は、 [object XPCNativeWrapper [object HTMLFormElement]] とかいうオブジェクトになっていて、安全のために、オブジェクトの要素に直にアクセスできないようになっているようです(´・ω・`)

// 入力値のチェックをしたい form エレメントを取得
var issue_form1 = document.getElementById ('issue-form');
// submit 時のハンドラを上書きする
issue_form1.onsubmit = function () {...};

form エレメントの submit イベントをフックしたい その2

 検索してみると、イベントをフックするには addEventListener を使うようです。書換えます。

// 入力値のチェックをしたい form エレメントを取得
var issue_form1 = document.getElementById ('issue-form');
// submit イベントにハンドラを追加
issue_form1.addEventListener ('submit', function () {
    alert ('飛び込んできたよ');
    // フォームは送信しない
    return false;
}, false);

 フォームを送信しようとするとアラートが出るようになりました。これで送信前に任意の処理を追加できるようになりました。しかし、false を返してもフォームが常に送信されてしまいます。条件によってフォームの送信を実行/禁止できません(´・ω・`)

submit する/しないようにする

 フォーム内に submit タイプのボタンが設置されているので、これを何とかしてみます。

// 送信ボタンを取得
var commit = document.getElementById ('commit');
// type="submit" を type="button" に置き換える
commit.setAttribute ('type', 'button');
// ボタンが押された時のハンドラを登録する
commit.addEventListener ('click', function () {
    // もし入力値のチェックがOKなら
    if (checking_condition)
        // フォームを送信する
        issue_form.submit();
}, false);

 これでようやく期待した動作になりました(・∀・) 何か変なことやってるなーと思われた方、こういう経過があったのです...