我有以下(相当)简单的JavaScript代码段,我已连接到Greasemonkey。它通过一个页面,寻找< a>标记的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(/&/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的新手,但这个让我难过!
答案 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元素的循环引用。