JavaScript(通过Greasemonkey)无法在<a> tags</a>上设置“标题”属性

时间:2009-01-09 10:54:33

标签: javascript html greasemonkey

我有以下(相当)简单的JavaScript代码段,我已连接到Greasemonkey。它通过一个页面,寻找&lt; a&gt;标记的href指向tinyurl.com,并添加标识链接真实目的地的“标题”属性。许多重要的代码都来自较旧的(不受支持的)Greasemonkey脚本,当运行XPath实现的内部组件发生更改时,该脚本将退出。我的剧本:

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

(“提供者”关联数组的设置原因是这样,我可以扩展它以覆盖其他URL缩短服务。)

我已经验证在正在检查的链接与模式匹配的情况下,是否正确访问了所有各种代码分支。什么发生,是对锚标签的“title”属性的任何更改。我通过Firebug观看了这个,向左和向右抛出alert()个电话,它永远不会改变。在前一次迭代中,所有表达式都为:

link.title = "...";

原来是:

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

这也没用。我不是JavaScript或Greasemonkey的新手,但这个让我难过!

1 个答案:

答案 0 :(得分:2)

请尝试使用此代码替换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元素的循环引用。