2

奇妙な問題があります。FirefoxとGoogleChromeで実行するGreaseMonkeyスクリプトを作成しようとしています。Chromeで、「TamperMonkey」と「Blank Canvas Script Handler」の2つの拡張機能を試しました。これは主に、スクリプトが外部サイトで新しいバージョンを定期的にチェックし、これがクロスサイトスクリプティングと見なされてChromeで許可されていないためです。

私の問題を示すために、簡単なテストケースを作成します。

// ==UserScript==
// @name        test
// @namespace       http://fgs.ericc-dream.fr.nf
// @description     test gm script
// @include         http://gaia.fallengalaxy.eu/
// @author          ericc
// @version         0.0.1
// ==/UserScript==

/* We attach an event listener to the body tag and trigger the function
 * 'message' each time that an element is inserted in the page */
var el = document.body;
el.addEventListener('DOMNodeInserted', message, false);

var extraFlag = false;

function message(event) {
    /* first we capture the id of the new inserted element
     * (the one who created the event) */
    var objId = event.target.id;

    /* add an event listener on the map container */
    if (objId == "extra") {
        el = document.getElementById('extra');
        el.addEventListener('DOMSubtreeModified',readTest,false);
        GM_log(el.style.display);
    }
}

function readTest() {
    el = document.getElementById('extra');
    GM_log(extraFlag);
    GM_log(el.style.display);
    if ((el.style.display != 'none') && (!extraFlag)) {
        alert('extra');
        extraFlag = true;
    } else if ((el.style.display == 'none')) {
        extraFlag = false;
    }
}

div要素'extra'はページによって変更されます。問題は、Chromeがel.style.displayの値を読み取ることができないため、extraFlagが再び「false」になることはないということです。私はこのフラグを使用して、コードを何度も実行しないようにしています。サイトはJavaScript駆動型です。このコードはFirefoxでうまく機能します。

Googleで検索しようとしましたが、正解が見つかりません。表示の値を変更するのは簡単なようですが、それを読もうとしているのは私だけのようです!!!

「DOMAttrModified」はChromeでサポートされていないため、このコードを記述します:-(

よろしくお願いします

ericc

4

2 に答える 2

3

あなたの質問が何であるかを正確に理解するのに苦労していますが、Chromeは.style.displayプロパティを問題なく読み取ることができるようです。次のコードをHTMLテンプレートに入れて、Chrome10にロードしました。

<div id="div1">
</div>

<div id="div2" style="display: block;">
</div>

<div id="div3" style="display: inline;">
</div>

<div id="div4" style="display: none;">
</div>

<script type="text/javascript">
    alert(document.getElementById("div1").style.display);
    alert(document.getElementById("div2").style.display);
    alert(document.getElementById("div3").style.display);
    alert(document.getElementById("div4").style.display);

    document.getElementById("div1").style.display = "none";

    alert(document.getElementById("div1").style.display);
</script>

このコードは、次の出力を持つ5つの「アラート」ボックスを生成しました。

  • ブロック
  • 列をなして
  • 無し
  • 無し

したがって、Chomeはこのプロパティを問題なく読み取るようです。

おそらく問題は、greasemonkeyスクリプトを実行しているWebページがChromeとFirefoxで異なる動作をしていることですか?要素のIDが異なるのか、要素が単に非表示になっているのではなく、DOMから削除されているのでしょうか。このように、さらにいくつかのチェックを使用して関数を変更するとどうなりますか?

function readTest() {
    el = document.getElementById('extra');
    if(el)
    {
        GM_log(extraFlag);
        GM_log(el.style.display);
        if (el.style.display && (el.style.display != 'none') && (!extraFlag)) {
            alert('extra');
            extraFlag = true;
        } else if ((el.style.display == 'none') || !el.style.display) {
            extraFlag = false;
        }
    }
    else
    {
        GM_log(extraFlag);
        GM_log("element not present");
        extraFlag = false;
    }
}

それは役に立ちますか?そうでない場合、el.style.displayがChromeで正しく評価されない理由を考えることができる他の理由はありますか?

スクリプトで何をしようとしているのか、そしておそらくこれを実行しようとしているWebページやコードについてもっと知っていれば役立つかもしれません。

于 2011-03-29T20:30:57.110 に答える
1

数時間と大量のテストケースの後、ようやく納得できる説明が見つかりました (ただし、まだ解決策ではありません!)

シナリオを説明しましょう:
1°) ユーザーが画面上のアイコンをクリックする
2°) ページに既に存在する div#extra は、その表示プロパティ (.style.display="") を削除することで表示されます。
3°) div#extra は、ユーザーがクリックしたアイコンに応じていくつかの要素を持つ AJAX 関数によってファイルされます (特定のケースでは 200 以上の要素)
4°) ユーザーが他のアイコンをクリックして div を閉じます
5° ) div#extra のすべての要素が削除されます
6°) div#extra は、表示プロパティを「none」(.style.display="none") にすることで非表示になります

最初は、Firefox で div#extra の「DOMAttrModified」イベントを使用して、表示プロパティがいつ変更されたかを確認し、それに応じて対応しました。問題、このイベントは Chrome ではサポートされていません!!

したがって、両方のブラウザでサポートされている " DOMSubtreeModified " (div#extra に添付) に置き換えます....しかし、まったく同じ方法ではありません :-(
Firefox では、サブツリーのすべての変更に対してイベントが発生しますが、要素自体が変更されたとき
Chromeでは、サブツリーの変更に対してのみもう少し厳密でイベントが発生します....そしてこれは私の問題です!

Firefox では、最初のイベントはポイント 2 (シナリオ内) で発生し、最後にポイント 6 で発生し、div#extra が非表示になったときに関数を読み取ることができます。

Chrome では、最初のイベントがポイント 3 で発生し、最後にポイント 5 で発生します。したがって、div#extra が非表示の場合、関数が呼び出されず、フラグを変更できません !!!! CQFD

さて、または、表示プロパティが変更されたときにインターセプトするイベント リスナーをページの本文に追加しますが、関数への呼び出しが大量に生成されます。または、TamperMonkey の開発者が昨日、彼の拡張機能が「DOMAttrModified 」をサポートするようになったと言いました。 " (Chrome) ....

とにかく、私の質問と提案された解決策を理解するために時間を割いてくれてありがとう

エリック

于 2011-03-31T08:06:52.067 に答える