Подтвердить что ты не робот

Метод jQuery.hasClass() не работает для элементов SVG

У меня есть набор элементов SVG с классами node и link. Моя программа должна определить, имеет ли элемент класс node или класс link при зависании над любым элементом SVG. Однако по какой-то причине .hasClass(), похоже, не работает:

$(".node").hover(function(evt){
    console.log($(this).attr("class")); //returns "node"
    console.log($(this).hasClass('node')); //returns false
}, function(){console.log("Done");});

Таким образом, элемент, на котором я навис, имеет класс node, и jQuery также обнаруживает это, как показано console.log($(this).attr("class"));, но по какой-то причине фактический .hasClass() терпит неудачу. Почему это? Неудачно ли из-за SVG?

4b9b3361

Ответ 1

Атрибут класса для элемента HTML не имеет такого же значения в SVG.

$("<b></b>").addClass($(this).attr("class")).hasClass("node")

или

/(^|\s)node(\s|$)/.test($(this).attr("class"))

для элементов SVG.

EDIT.hasClass работает нормально (по крайней мере, в IE9 и FF) http://jsfiddle.net/X6BPX/1/ p >

Таким образом, проблема может быть любой комбинацией следующего: синтаксическая ошибка с использованием устаревшего браузера с использованием устаревшей версии jQuery.

Ответ 2

Как отмечал Берги в комментариях, jQuery бесшумно терпит неудачу в SVG-элементах за счет className возвращает объект SVGAnimatedString вместо обычного DOMString.

См. этот JSFiddle для сравнения.

У меня возникло соблазн представить запрос на перенос, но сделал быстрый поиск по проекту, и, по-видимому, позиция проекта jQuery в вопросах SVG - это wontfix: https://github.com/jquery/jquery/pull/1511

Если вы используете D3, вы можете использовать d3.select(this).classed('node'). Обратите внимание, что D3 правильно возвращает как для HTML-элементов, так и для элементов SVG.

Ответ 3

Это не самый быстрый вариант, но это возможное решение. Вместо использования jQuery hasClass вместо этого вы можете получить атрибут class в качестве строки и использовать indexOf для поиска по нему. Вероятно, есть случаи, когда это не удастся, поэтому я бы не рекомендовал этого, кроме супер простых проектов.

Рабочий пример:

var s = $(this).attr('class');
if( s.indexOf('node')!==-1 ){
    // do something
}

Помните: indexOf возвращает -1, когда он ничего не может найти, а не 0. 0 возвращается, когда подстрока начинается с индекса 0.

Ответ 4

Это взломать методы addClass, removeClass, hasClass jquery перед версиями jquery 3.x.x.

$.fn.extend({
    addSVGClass: function (cls) {
        return this.each(function () {
            var classList = $(this).attr('class');
            if (classList) {
                var classListArr = classList.split(" ");
                if (classListArr.indexOf(cls) === -1) {
                    classListArr.push(cls);
                    classList = classListArr.join(" ").trim();
                    $(this).attr('class', classList);
                }
            } else {
                $(this).attr('class', cls);
            }
        });
    },
    removeSVGClass: function (cls) {
        return this.each(function () {
            var classList = $(this).attr('class');
            if (classList) {
                var classListArr = classList.split(" ");
                if (classListArr.indexOf(cls) !== -1) {
                    delete classListArr[classListArr.indexOf(cls)];
                    classList = classListArr.join(" ").trim();
                    $(this).attr('class', classList);
                }
            }

        });
    },
    hasSVGClass: function (cls) {
        var el = this[0];
        var classList = $(el).attr('class');
        if (classList) {
            var classListArr = classList.split(" ");
            if (classListArr.indexOf(cls) !== -1) {
                return true;

            } else {
                return false;
            }
        }
        return false;
    }
});

использование:

$('.svg-element').addSVGClass('selected');

Ответ 5

Работает. Но не забудьте закрыть функцию

$(".node").hover(function(evt){
    console.log($(this).attr("class")); //returns "node"
    console.log($(this).hasClass('node')); //returns false
}, function(){console.log("Done");});

http://jsfiddle.net/X6BPX/