JavaScript (via Greasemonkey) ne parvient pas à définir les attributs "titre" sur < a > Mots clés

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

  •  06-07-2019
  •  | 
  •  

Question

J'ai l'extrait de code JavaScript suivant (assez) simple que j'ai câblé dans Greasemonkey. Il parcourt une page, recherche < un > les balises dont href pointe sur tinyurl.com , et ajoute un "titre". attribut qui identifie la vraie destination du lien. Une grande partie du code important provient d'un script Greasemonkey plus ancien (non pris en charge) qui cesse de fonctionner lorsque le composant interne contenant l'implémentation de XPath a été modifié. Mon script:

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

(Si le tableau associatif des "fournisseurs" est configuré tel quel, c'est pour que je puisse l'étendre également à d'autres services de réduction du nombre d'URL.)

J'ai vérifié que toutes les différentes branches de code étaient atteintes correctement, dans les cas où le lien examiné correspondait ou non au modèle. Ce qui ne se produit pas , n’est-ce pas une modification du & titre; titre " attribut des balises d'ancrage. J'ai regardé cela via Firebug, jeté les appels alert () à gauche et à droite, et cela ne change jamais. Dans une itération précédente, toutes les expressions du formulaire:

link.title = "...";

avait été à l'origine:

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

Cela n'a pas fonctionné non plus. Je ne suis pas un débutant dans JavaScript OR Greasemonkey, mais celui-ci m'a laissé perplexe!

Était-ce utile?

La solution

Essayez de remplacer le corps du if par ce code.

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

Remarque une fois la boucle terminée, faites aTags = null; .

Votre problème, c’est qu’un bloc d’instruction if n’est pas une vraie portée, tout ce qui est var'd appartiendra à la portée des fonctions externes. Par conséquent, votre fonction interne que vous fournissez en tant que gestionnaire d'événements utiliserait la source, le lien et le fragment de la dernière passe. De plus, en conservant les références à un objet DOM, vous risquez une fuite de mémoire en raison de références circulaires.

L’approche ci-dessus crée une nouvelle portée à chaque passage via un appel de fonction afin que chaque source et fragment se trouve dans sa propre portée. Il utilise également le fait qu'une fonction appelée en tant qu'écouteur d'événements a la propriété this pointant sur l'élément auquel elle est attachée, évitant ainsi une référence circulaire contenant un élément DOM.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top