我有一组包含node
和link
类的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失败了吗?
答案 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");});