jQuery Selector + SVG不兼容?

时间:2010-07-20 21:33:42

标签: javascript jquery xhtml jquery-selectors svg

我一直在使用带有内联SVG和javascript动画的HTML5文档。

当用户点击任意位置时,我想弹出一个框,当用户点击不是框的地方时,我希望该框能够消失。这意味着我无法使用有效的$(window).click()

我尝试通过给出类名并使用$(".svgclassname").click()来选择顶部的SVG,但这似乎不起作用。也没有使用$("#svgname").click()选择单个的。

有什么问题?

(当我用$(".eyesvg")替换$(window)时,当用户点击窗口中的任意位置时,光标附近会出现一个蓝色框。)

3 个答案:

答案 0 :(得分:67)

这是因为SVG DOM规范与HTML DOM有很大不同。

SVG DOM是一种不同的方言,有些属性具有相同的名称,但意思不同。例如,要获取svg元素的className,请使用:

svg.className.baseVal

受此影响的人才

className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength

这些动画属性是结构体,baseVal保持您在HTML DOM中找到的相同值,animatedVal保持我不确定是什么。

SVG DOM也缺少某些属性库所依赖的属性,例如innerHTML

这会以多种方式破坏jQuery,任何依赖于上述属性的东西都会失败。

通常,SVG DOM和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);

它创建了一个围绕SVG对象的包装器,使它们看起来像HTML DOM到jQuery。我已经将它与jQuery-UI一起使用,以使我的SVG元素可以删除。

HTML和SVG之间缺乏DOM互操作性是一场灾难。为HTML编写的所有甜蜜实用程序库都必须为SVG重新创建。

答案 1 :(得分:4)

有时候我得不到它......但实际上它并不适用于类选择器。如果你使用id $(“#mysvg”)或元素$(“svg”)它确实有效!奇怪....

它只适用于在svg元素之后将onClick脚本从标题移动到正文时! jquery只能在绑定之前声明元素时绑定onclick。

答案 2 :(得分:4)

你可以使用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>