jQuery Selector + SVG Несовместимо? - PullRequest
37 голосов
/ 21 июля 2010

Я работал с документом HTML5 со встроенной SVG и анимацией JavaScript.

Мне бы хотелось, чтобы окно появлялось, когда пользователь щелкает в любом месте, и я хотел бы, чтобы поле исчезало, когда пользователь щелкает где-то, кроме поля. Это означает, что я не могу использовать $(window).click(), который работает.

Я пытался выбрать SVG сверху, дав им имена классов и используя $(".svgclassname").click(), но, похоже, это не сработало. Также не выбираются отдельные с $("#svgname").click().

В чем проблема?

(Когда я заменяю $(".eyesvg") на $(window), рядом с курсором появляется синее поле, когда пользователь щелкает в любом месте окна.)

Ответы [ 3 ]

67 голосов
/ 22 апреля 2011

Это происходит потому, что спецификация SVG DOM сильно отличается от HTML DOM.

SVG DOM - это другой диалект, и некоторые свойства имеют одинаковые имена, но означают разные вещи.Например, чтобы получить className элемента svg, вы используете:

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-элементы можно было переключать.

Отсутствие взаимодействия DOM между HTML и SVG является полной катастрофой.Все полезные служебные библиотеки, написанные для HTML, должны быть заново изобретены для SVG.

4 голосов
/ 19 марта 2016

вы можете использовать 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>
4 голосов
/ 21 июля 2010

иногда я не понимаю ... но на самом деле это не работает с селектором классов. Если вы используете идентификатор $ ("# mysvg") или элемент $ ("svg"), это работает! Странно ....

И это работает только тогда, когда вы перемещаете скрипт onClick из заголовка в тело после элемента svg! jquery может связывать onclick только тогда, когда элемент объявлен перед привязкой.

...