jQuery .hasClass() method fails for SVG elements

I have a set of SVG elements with the classes node and link. My program should detect whether an element has the node class or the link class upon hovering over any of the SVG elements. However, for some reason, the .hasClass() doesn't seem to work:

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

So the element I hovered on has the class node, and jQuery detects that too, as shown by console.log($(this).attr("class"));, but for some reason the actual .hasClass() fails. Why is this? Is it failing because of the SVG?

Answers


The class attribute for HTML element doesn't have the same meaning in SVG.

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

Or

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

for SVG elements.

EDIT .hasClass seems to work just fine (at least in IE9 and FF) http://jsfiddle.net/X6BPX/1/

So the problem could be any combination of the following: a syntax error, using an outdated browser, using an outdated version of jQuery.


As Bergi pointed out in comments, jQuery silently fails on SVG elements on account of className returning an SVGAnimatedString object instead of a normal DOMString.

See this JSFiddle for a comparison.

I was tempted to submit a pull request on this, but did a quick project search, and apparently the jQuery project stance on SVG issues is wontfix: https://github.com/jquery/jquery/pull/1511

If you're using D3, you could use d3.select(this).classed('node'). Note that D3 correctly returns for both HTML elements and SVG elements.


This is not the fastest option ever, but it is a possible solution. Instead of using jQuery's hasClass you could instead obtain the class attribute as a string and use indexOf to search through it. There are probably use cases where this will fail, so I wouldn't recommend this except for super simple projects.

Working example:

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

Remember: indexOf returns -1 when it can't find anything, not 0. 0 is returned when the substring starts at index 0.


This is a hack for addClass, removeClass, hasClass jquery methods for before jquery 3.x.x versions.

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

usage :

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

Works. But be sure to close the function

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


Need Your Help

Natural Sorting algorithm

algorithm language-agnostic sorting natural-sort

How do you sort an array of strings naturally in different programming languages? Post your implementation and what language it is in in the answer.

WPF or Windows Forms

c# wpf windows winforms c#-4.0

I've been playing around with C# console applications for about a year and I want to move on to creating GUI applications. I have never done any GUI development besides basic Java applications, but I