jQuery Selector + SVG不兼容?

Wil*_*ill 37 javascript xhtml jquery svg jquery-selectors

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

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

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

问题是什么?

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

Ale*_*tic 67

发生这种情况是因为SVG DOM规范与HTML DOM有很大不同.

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

svg.className.baseVal
Run Code Online (Sandbox Code Playgroud)

受此影响的人才是

className is SVGAnimatedString
height,width, x, y, offsetWidth, offsetHeight are SVGAnimatedLength
Run Code Online (Sandbox Code Playgroud)

这些动画属性是结构体,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);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 嘿有Aleksander,谢谢你的建议!该片段让我们走得很远,但由于在使用SVG DOM元素直接使用原型继承时出现错误,因此在Firefox 15中无效.我们已将其修改为在Firefox中运行并正在成功使用它.代码在这里:http://github.com/RedBrainLabs/jquery.wrap-svg (7认同)

moh*_*eti 5

你可以使用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>
Run Code Online (Sandbox Code Playgroud)