jQuery .hasClass() method fails for SVG elements

后端 未结 5 1832
挽巷
挽巷 2021-02-18 14:51

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 l

相关标签:
5条回答
  • 2021-02-18 15:16

    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.

    0 讨论(0)
  • 2021-02-18 15:19

    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');
    
    0 讨论(0)
  • 2021-02-18 15:23

    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/

    0 讨论(0)
  • 2021-02-18 15:28

    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.

    0 讨论(0)
  • 2021-02-18 15:29

    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.

    0 讨论(0)
提交回复
热议问题