对于SVG元素,jQuery .hasClass()方法失败

时间:2013-07-24 17:34:48

标签: javascript jquery html css svg

我有一组包含nodelink类的SVG元素。我的程序应该在将鼠标悬停在任何SVG元素上时检测元素是否具有node类或link类。但是,出于某种原因,.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失败了吗?

5 个答案:

答案 0 :(得分:11)

HTML元素的class属性在SVG中的含义不同。

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

或者

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

用于SVG元素。

编辑 .hasClass似乎工作得很好(至少在IE9和FF中)http://jsfiddle.net/X6BPX/1/

所以问题可能是以下任意组合:语法错误,使用过时的浏览器,使用过时的jQuery版本。

答案 1 :(得分:5)

正如Bergi在评论中指出的那样,由于className返回SVGAnimatedString对象而不是正常的DOMString,jQuery在SVG元素上默默失败。

请参阅this JSFiddle进行比较。

我很想提交一个pull请求,但是做了一个快速的项目搜索,显然jQuery项目对SVG问题的立场是wontfix:https://github.com/jquery/jquery/pull/1511

如果您正在使用D3,则可以使用d3.select(this).classed('node')。请注意,D3正确返回HTML元素和SVG元素。

答案 2 :(得分:4)

这不是有史以来最快的选择,但它是一种可能的解决方案。您可以使用hasClass属性作为字符串,而不是使用jQuery的class,并使用indexOf来搜索它。可能会出现失败的用例,所以除了超级简单的项目外,我不建议这样做。

工作示例:

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

请记住:indexOf在找不到任何内容时返回-1,而不是0。子字符串从索引0开始时返回0

答案 3 :(得分:1)

这是jquery 3.x.x版本之前的addClass,removeClass,hasClass jquery方法的hack。

$.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');

答案 4 :(得分:-4)

作品。但一定要关闭功能

$(".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/