JavaScript (через Greasemonkey) не может установить атрибуты title в тегах <a>

У меня есть следующий (довольно) простой фрагмент кода JavaScript, который я подключил к Greasemonkey. Он просматривает страницу, ищет теги <a>, href которых указывает на tinyurl.com, и добавляет атрибут «title», который определяет истинное место назначения ссылки. Большая часть важного кода происходит из более старого (неподдерживаемого) скрипта 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, но этот меня поставил в тупик!

Попытайтесь сократить свой код до минимума, в котором ошибка все еще присутствует.

Rene Saarsoo 09.01.2009 14:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
2 349
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вместо этого попробуйте заменить корпус 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.

если обзор - такая большая проблема ... +1

annakata 09.01.2009 14:53

Отлично ... Попробую. Я подозреваю, что вы категорически против, так как причина для назначения источника / фрагмента / ссылки, а не их прямого использования, заключалась в том, что они «таинственным образом» выходили за рамки. Замыкания JS! = Замыкания Perl!

rjray 09.01.2009 15:12

Другие вопросы по теме