22

我有一组带有类的 SVG 元素nodelink. 我的程序应该在悬停在任何 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");});

所以我悬停的元素有 class node,jQuery 也检测到了,如 所示console.log($(this).attr("class"));,但由于某种原因实际.hasClass()失败了。为什么是这样?是否因为 SVG 而失败?

4

5 回答 5

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 版本。

于 2013-07-24T17:41:37.463 回答
7

正如 Bergi 在评论中指出的那样,jQuery 在 SVG 元素上静默失败,因为它className返回的是SVGAnimatedString对象而不是普通的DOMString.

请参阅此 JSFiddle进行比较。

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

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

于 2014-07-15T14:45:27.877 回答
4

这不是有史以来最快的选择,但它是一种可能的解决方案。除了使用 jQuery,hasClass您还可以将class属性作为字符串获取并用于indexOf搜索它。可能有一些用例会失败,所以除了超级简单的项目外,我不会推荐这个。

工作示例:

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

请记住:在找不到任何东西时indexOf返回,而不是. 当子字符串从 index 开始时返回。-1000

于 2015-09-24T21:01:15.900 回答
1

这是针对 jquery 3.xx 版本之前的 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');
于 2017-10-13T02:48:50.827 回答
-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/

于 2013-07-24T17:46:44.420 回答