JavaScript (tramite Greasemonkey) non riesce a impostare gli attributi "title" su < a > tag

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

  •  06-07-2019
  •  | 
  •  

Domanda

Ho il seguente frammento JavaScript (abbastanza) semplice che ho collegato a Greasemonkey. Passa attraverso una pagina, cerca < a > tag il cui href punta a tinyurl.com e aggiunge un " titolo " attributo che identifica la vera destinazione del collegamento. Gran parte del codice importante deriva da uno script Greasemonkey precedente (non supportato) che smette di funzionare quando il componente interno che conteneva l'implementazione di XPath è cambiato. La mia sceneggiatura:

(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);
        }
    }
})();

(Il motivo per cui l'array associativo "provider" è impostato così com'è è che posso estenderlo per coprire anche altri servizi di abbreviazione di URL.)

Ho verificato che tutti i vari rami del codice sono stati raggiunti correttamente, nei casi in cui il collegamento in esame fa e non corrisponde al modello. Ciò che non sta sta succedendo, è una modifica al "titolo" attributo dei tag anchor. L'ho visto tramite Firebug, ho lanciato le chiamate alert () a sinistra e a destra e non cambia mai. In una precedente iterazione tutte le espressioni del modulo:

link.title = "...";

era stato originariamente:

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

Neanche quello ha funzionato. Non sono un novizio di JavaScript o Greasemonkey, ma questo mi ha lasciato perplesso!

È stato utile?

Soluzione

Prova invece a sostituire il corpo del if con questo codice

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

Nota al termine del ciclo, eseguire aTags = null; .

Il tuo problema è che un blocco di istruzioni if ??non è un ambito vero, qualsiasi cosa var'd apparirà all'ambito delle funzioni esterne. Quindi la tua funzione interiore che stai fornendo come gestore di eventi userebbe l'origine, il collegamento e il frammento dell'ultimo passaggio. Inoltre, mantenendo i riferimenti all'oggetto DOM si avrebbe una perdita di memoria dovuta a riferimenti circolari.

L'approccio di cui sopra crea un nuovo ambito su ogni passaggio tramite una chiamata di funzione in modo che ogni sorgente e frammento sia nel proprio ambito. Utilizza anche il fatto che una funzione chiamata come listener di eventi ha la proprietà this che punta all'elemento a cui è collegata, evitando quindi un riferimento circolare contenente un elemento DOM.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top