JavaScript (a través de Greasemonkey) no puede establecer atributos de "título" en < a > etiquetas

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

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo el siguiente fragmento de JavaScript (bastante) simple que he conectado a Greasemonkey. Pasa por una página, busca < a > etiquetas cuyo href apunta a tinyurl.com y agrega un " título " atributo que identifica el verdadero destino del enlace. Gran parte del código importante proviene de un script de Greasemonkey anterior (no compatible) que deja de funcionar cuando cambia el componente interno que contenía la implementación de XPath. Mi guión:

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

(La razón por la que la matriz asociativa de "proveedores" está configurada de la manera que es, es para que pueda expandir esto para cubrir también otros servicios de acortamiento de URL).

He verificado que se alcanzan correctamente todas las distintas ramas del código, en los casos en que el enlace que se examina coincide y no coincide con el patrón. Lo que no está sucediendo, es cualquier cambio en el " título " atributo de las etiquetas de anclaje. He visto esto a través de Firebug, lanzo llamadas alert () a izquierda y derecha, y nunca cambia. En una iteración anterior, todas las expresiones de la forma:

link.title = "...";

originalmente había sido:

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

Eso tampoco funcionó. No soy un novato en JavaScript O Greasemonkey, ¡pero este me tiene perplejo!

¿Fue útil?

Solución

Intente reemplazar el cuerpo del if con este código en su lugar.

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

Nota después de que se complete el ciclo, haga aTags = null; .

Su problema es que un bloque de instrucción if no es un alcance verdadero, cualquier cosa pertenecerá al alcance de las funciones externas. Por lo tanto, su función interna que está proporcionando como controlador de eventos utilizaría la fuente, el enlace y el fragmento de la última pasada. Además, al mantener referencias al objeto DOM, tendría una pérdida de memoria debido a referencias circulares.

El enfoque anterior crea un nuevo alcance en cada paso a través de una llamada de función para que cada fuente y fragmento esté en su propio alcance. También utiliza el hecho de que una función llamada como detector de eventos tiene la propiedad this apuntando al elemento al que está asociada, evitando así una referencia circular que contenga un elemento DOM.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top