JavaScript(通过Greasemonkey)未能在< a>上设置“title”属性标签

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

  •  06-07-2019
  •  | 
  •  

我有以下(相当)简单的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(/&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缩短服务。)

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

link.title = "...";

原来是:

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

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

有帮助吗?

解决方案

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top