JavaScript(Greasemonkey経由)で“ title”を設定できない< a>の属性タグ

StackOverflow https://stackoverflow.com/questions/427679

  •  06-07-2019
  •  | 
  •  

質問

Greasemonkeyに配線した以下の(かなり)簡単なJavaScriptスニペットがあります。ページをたどり、< a>を探します。 hrefが tinyurl.com を指し、" title"を追加するタグリンクの実際の宛先を識別する属性。重要なコードの多くは、XPath実装を保持する内部コンポーネントが変更されたときに動作を終了する古い(サポートされていない)Greasemonkeyスクリプトからのものです。私のスクリプト:

(function() {
    var providers = new Array();
    providers['tinyurl.com'] = function(link, fragment) {
        // This is mostly taken from the (broken due to XPath component
        // issues) tinyurl_popup_preview script.
        link.title = "Loading...";
        GM_xmlhttpRequest({
                method: 'GET',
                url: 'http://preview.tinyurl.com/' + fragment,
                onload: function(res) {
                    var re = res.responseText.match("<blockquote><b>(.+)</b></blockquote>");
                    if (re)
                    {
                        link.title = re[1].replace(/\<br \/\>/g, "").replace(/&amp;/g, "&");
                    }
                    else
                    {
                        link.title = "Parsing failed...";
                    }
                },
                onerror: function() {
                    link.title = "Connection failed...";
                }
        });
    };
    var uriPattern = /(tinyurl\.com)\/([a-zA-Z0-9]+)/;
    var aTags = document.getElementsByTagName("a");

    for (i = 0; i < aTags.length; i++)
    {
        var data = aTags[i].href.match(uriPattern);
        if (data != null && data.length > 1 && data[2] != "preview")
        {
            var source = data[1];
            var fragment = data[2];
            var link = aTags[i];
            aTags[i].addEventListener("mouseover", function() {
                if (link.title == "")
                {
                    (providers[source])(link, fragment);
                }
            }, false);
        }
    }
})();

(&quot; providers&quot;連想配列がそのまま設定される理由は、他のURL短縮サービスにも対応できるようにこれを拡張できるようにするためです。)

調査対象のリンクがパターンに一致する場合と一致しない場合に、コードのすべての分岐に正しく到達していることを確認しました。何が起こっていないか は、「タイトル」への変更です。アンカータグの属性。 Firebugでこれを見て、左右に alert()呼び出しをスローしましたが、変更されることはありません。前の反復では、次の形式のすべての式:

link.title = "...";

元々:

link.setAttribute("title", "...");

それでもうまくいきませんでした。私はJavaScriptやGreasemonkeyの初心者ではありませんが、これには困惑しています!

役に立ちましたか?

解決

if の本文を代わりにこのコードに置き換えてみてください。

        aTags[i].addEventListener("mouseover", (function(source, fragment)
        {
            return function()
            {
                if (this.title == "")
                {
                    (providers[source])(this, fragment);
                }
            }
        })(data[1], data[2]), false) ; 

ループが完了した後、 aTags = null; を実行します。

問題は、ifステートメントブロックが真のスコープではないため、var'dのすべてが外部関数スコープに属することです。したがって、イベントハンドラーとして提供する内部関数は、最後のパスのソース、リンク、およびフラグメントを使用します。さらに、DOMオブジェクトへの参照を維持すると、循環参照によるメモリリークが発生します。

上記の方法では、関数呼び出しを介してパスごとに新しいスコープが作成されるため、各ソースとフラグメントは独自のスコープ内にあります。また、イベントリスナーとして呼び出される関数には、アタッチ先の要素を指す this プロパティがあるため、DOM要素を含む循環参照が回避されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top