Javascript jQuery 选择器 + SVG 不兼容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3294553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery Selector + SVG Incompatible?
提问by Will
I've been working with an HTML5 document with inline SVG and javascript animation.
我一直在处理带有内联 SVG 和 javascript 动画的 HTML5 文档。
I'd like to have a box pop up when the user clicks anywhere, and I'd like the box to go away when the user clicks somewhere that isn't the box. This means I can't use $(window).click(), which works.
当用户点击任何地方时,我希望弹出一个框,当用户点击某个不是框的地方时,我希望框消失。这意味着我不能使用$(window).click(),这是有效的。
I've tried selecting the SVGs on top by giving them class names and using $(".svgclassname").click(), but this doesn't seem to work. Neither does selecting individual ones with $("#svgname").click().
我已经尝试通过给它们类名和使用来选择顶部的 SVG $(".svgclassname").click(),但这似乎不起作用。用 选择单个的也不行$("#svgname").click()。
What is the problem?
问题是什么?
(When I replace $(".eyesvg")with $(window), a blue box appears near the cursor when the user clicks anywhere in the window.)
(当我替换$(".eyesvg")为 时$(window),当用户单击窗口中的任意位置时,光标附近会出现一个蓝色框。)
回答by Aleksandar Totic
This happens because SVG DOM spec differs a lot from HTML DOM.
发生这种情况是因为 SVG DOM 规范与 HTML DOM 有很大不同。
SVG DOM is a different dialect, and some properties have same names but mean different things. For example, to get the className of an svg element, you use:
SVG DOM 是一种不同的方言,有些属性具有相同的名称但含义不同。例如,要获取 svg 元素的 className,请使用:
svg.className.baseVal
The properites affected by this are
受此影响的属性是
className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
These Animated properties are structs, with baseValholding the same value you'd find in HTML DOM and animatedValholding I am not sure what.
这些 Animated 属性是结构体,其baseVal值与您在 HTML DOM 中找到的值相同,但animatedVal我不确定是什么。
SVG DOM is also missing some properties libraries depend on, such as innerHTML.
SVG DOM 还缺少一些依赖的属性库,例如innerHTML.
This breaks jQuery in many ways, anything that depends on above properties fails.
这在很多方面破坏了 jQuery,任何依赖于上述属性的东西都会失败。
In general, SVG DOM and HTML DOM do not mix very well. They work together just enough to lure you in, and then things break quietly, and another angel loses its wings.
一般来说,SVG DOM 和 HTML DOM 不能很好地混合。他们一起工作足以引诱你进入,然后事情悄悄地破裂,另一个天使失去了翅膀。
I wrote a little jQuery extension that wraps SVG elements to make them look more like HTML DOM
我写了一个小的 jQuery 扩展来包装 SVG 元素,使它们看起来更像 HTML DOM
(function (jQuery){
function svgWrapper(el) {
this._svgEl = el;
this.__proto__ = el;
Object.defineProperty(this, "className", {
get: function(){ return this._svgEl.className.baseVal; },
set: function(value){ this._svgEl.className.baseVal = value; }
});
Object.defineProperty(this, "width", {
get: function(){ return this._svgEl.width.baseVal.value; },
set: function(value){ this._svgEl.width.baseVal.value = value; }
});
Object.defineProperty(this, "height", {
get: function(){ return this._svgEl.height.baseVal.value; },
set: function(value){ this._svgEl.height.baseVal.value = value; }
});
Object.defineProperty(this, "x", {
get: function(){ return this._svgEl.x.baseVal.value; },
set: function(value){ this._svgEl.x.baseVal.value = value; }
});
Object.defineProperty(this, "y", {
get: function(){ return this._svgEl.y.baseVal.value; },
set: function(value){ this._svgEl.y.baseVal.value = value; }
});
Object.defineProperty(this, "offsetWidth", {
get: function(){ return this._svgEl.width.baseVal.value; },
set: function(value){ this._svgEl.width.baseVal.value = value; }
});
Object.defineProperty(this, "offsetHeight", {
get: function(){ return this._svgEl.height.baseVal.value; },
set: function(value){ this._svgEl.height.baseVal.value = value; }
});
};
jQuery.fn.wrapSvg = function() {
return this.map(function(i, el) {
if (el.namespaceURI == "http://www.w3.org/2000/svg" && !('_svgEl' in el))
return new svgWrapper(el);
else
return el;
});
};
})(window.jQuery);
It creates a wrapper around SVG objects that makes them look like HTML DOM to jQuery. I've used it with jQuery-UI to make my SVG elements droppable.
它围绕 SVG 对象创建了一个包装器,使它们看起来像 jQuery 的 HTML DOM。我已经将它与 jQuery-UI 一起使用,使我的 SVG 元素可放置。
The lack of DOM interoperability between HTML and SVG is a total disaster. All the sweet utility libraries written for HTML have to be reinvented for SVG.
HTML 和 SVG 之间缺乏 DOM 互操作性是一场彻头彻尾的灾难。所有为 HTML 编写的甜蜜实用程序库都必须为 SVG 重新发明。
回答by r?ph
sometimes I don't get it... but actually it doesn't work with the class-selector. If you use the id $("#mysvg") or the element $("svg") it does work! Strange....
有时我不明白……但实际上它不适用于类选择器。如果您使用 id $("#mysvg") 或元素 $("svg") 它确实有效!奇怪的....
And it only works when you move the onClick script from the header to the body after the svg element! jquery can only bind the onclick when the element is declared before the binding.
它仅在您将 onClick 脚本从标题移动到 svg 元素之后的正文时才有效!jquery只能在绑定之前声明元素时绑定onclick。
回答by mohammadreza berneti
u can use jquery-svgplugin, like a charm:
你可以使用jquery-svg插件,就像一个魅力:
<script>
//get svg object, like a jquery object
var svg = $("#cars").getSVG();
//use jquery functions to do some thing
svg.find("g path:first-child()").attr('fill', color);
</script>

