295

jQuery SVG を使用しています。オブジェクトにクラスを追加または削除できません。誰かが私の間違いを知っていますか?

SVG:

<rect class="jimmy" id="p5" x="200" y="200" width="100" height="100" />

クラスを追加しないjQuery:

$(".jimmy").click(function() {
    $(this).addClass("clicked");
});

オブジェクトをターゲットにして、クリックされたときにアラートを発生させることができるため、SVG と jQuery がうまく連携していることはわかっています。

$(".jimmy").click(function() {
    alert('Handler for .click() called.');
});
4

15 に答える 15

433

編集 2016: 次の 2 つの回答を読んでください。

  • JQuery 3 は根本的な問題を修正します
  • Vanilla JS:element.classList.add('newclass')最新のブラウザーで動作します

JQuery (3 未満) は SVG にクラスを追加できません。

.attr()SVG で動作するため、jQuery に依存する場合:

// Instead of .addClass("newclass")
$("#item").attr("class", "oldclass newclass");
// Instead of .removeClass("newclass")
$("#item").attr("class", "oldclass");

jQuery に依存したくない場合は、次のようにします。

var element = document.getElementById("item");
// Instead of .addClass("newclass")
element.setAttribute("class", "oldclass newclass");
// Instead of .removeClass("newclass")
element.setAttribute("class", "oldclass");
于 2012-04-21T09:27:21.300 に答える
76

DOM API には、HTML 要素と SVG 要素の両方で機能するelement.classListがあります。jQuery SVG プラグインや jQuery さえも必要ありません。

$(".jimmy").click(function() {
    this.classList.add("clicked");
});
于 2013-04-04T21:06:45.120 に答える
38

動的クラスがある場合、またはどのクラスが既に適用されているかわからない場合は、この方法が最善の方法だと思います。

// addClass
$('path').attr('class', function(index, classNames) {
    return classNames + ' class-name';
});

// removeClass
$('path').attr('class', function(index, classNames) {
    return classNames.replace('class-name', '');
});
于 2013-11-26T15:31:28.313 に答える
17

上記の回答に基づいて、次の API を作成しました

/*
 * .addClassSVG(className)
 * Adds the specified class(es) to each of the set of matched SVG elements.
 */
$.fn.addClassSVG = function(className){
    $(this).attr('class', function(index, existingClassNames) {
        return ((existingClassNames !== undefined) ? (existingClassNames + ' ') : '') + className;
    });
    return this;
};

/*
 * .removeClassSVG(className)
 * Removes the specified class to each of the set of matched SVG elements.
 */
$.fn.removeClassSVG = function(className){
    $(this).attr('class', function(index, existingClassNames) {
        var re = new RegExp('\\b' + className + '\\b', 'g');
        return existingClassNames.replace(re, '');
    });
    return this;
};
于 2014-06-12T22:28:00.430 に答える
13

ロード後jquery.svg.js、このファイルをロードする必要があります: http://keith-wood.name/js/jquery.svgdom.js.

ソース: http://keith-wood.name/svg.html#dom

作業例: http://jsfiddle.net/74RbC/99/

于 2011-12-27T00:18:38.697 に答える
7

不足しているプロトタイプ コンストラクターをすべての SVG ノードに追加するだけです。

SVGElement.prototype.hasClass = function (className) {
  return new RegExp('(\\s|^)' + className + '(\\s|$)').test(this.getAttribute('class'));
};

SVGElement.prototype.addClass = function (className) { 
  if (!this.hasClass(className)) {
    this.setAttribute('class', this.getAttribute('class') + ' ' + className);
  }
};

SVGElement.prototype.removeClass = function (className) {
  var removedClass = this.getAttribute('class').replace(new RegExp('(\\s|^)' + className + '(\\s|$)', 'g'), '$2');
  if (this.hasClass(className)) {
    this.setAttribute('class', removedClass);
  }
};

その後、jQuery を必要とせずにこの方法で使用できます。

this.addClass('clicked');

this.removeClass('clicked');

すべての功績はTodd Motoにあります。

于 2014-11-19T19:56:02.297 に答える
5

jQuery 2.2 は SVG クラス操作をサポートします

jQuery 2.2 および 1.12 のリリースされた投稿には、次の引用が含まれています。

jQuery は HTML ライブラリですが、SVG 要素のクラス サポートが役立つ可能性があることに同意しました。ユーザーは、SVG で .addClass( ).removeClass().toggleClass()、および.hasClass()メソッドを呼び出すことができるようになりました。jQueryは、className プロパティではなく、class 属性を変更するようになりました。これにより、クラス メソッドを一般的な XML ドキュメントで使用できるようになります。他の多くのことは SVG では機能しないことに注意してください。クラス操作以外のことが必要な場合は、SVG 専用のライブラリを使用することをお勧めします。

jQuery 2.2.0を使用した例

以下をテストします。

  • .addClass()
  • .removeClass()
  • .hasClass()

その小さな四角をクリックすると、class属性が追加/削除されるため、色が変わります。

$("#x").click(function() {
    if ( $(this).hasClass("clicked") ) {
        $(this).removeClass("clicked");
    } else {
        $(this).addClass("clicked");
    }
});
.clicked {
    fill: red !important;  
}
<html>

<head>
    <script src="https://code.jquery.com/jquery-2.2.0.js"></script>
</head>

<body>
    <svg width="80" height="80">
        <rect id="x" width="80" height="80" style="fill:rgb(0,0,255)" />
    </svg>
</body>

</html>

于 2016-01-09T19:35:23.647 に答える
5

jQuery は SVG 要素のクラスをサポートしていません。要素を直接取得して、と$(el).get(0)を使用できます。最上位の SVG 要素は実際には通常の DOM オブジェクトであり、jQuery の他のすべての要素と同じように使用できるという点で、これにもトリックがあります。私のプロジェクトでは、必要なものを処理するためにこれを作成しましたが、Mozilla Developer Networkで提供されているドキュメントには、代替として使用できる shim があります。classListadd / remove

function addRemoveClass(jqEl, className, addOrRemove) 
{
  var classAttr = jqEl.attr('class');
  if (!addOrRemove) {
    classAttr = classAttr.replace(new RegExp('\\s?' + className), '');
    jqEl.attr('class', classAttr);
  } else {
    classAttr = classAttr + (classAttr.length === 0 ? '' : ' ') + className;
    jqEl.attr('class', classAttr);
  }
}

代わりに、代わりに D3.js をセレクター エンジンとして使用するのは、さらに難しい方法です。私のプロジェクトには、それを使用して作成されたチャートがあるため、アプリのスコープにも含まれています。D3 は、通常の DOM 要素と SVG 要素のクラス属性を正しく変更します。ただし、この場合に D3 を追加するのはやり過ぎになる可能性があります。

d3.select(el).classed('myclass', true);
于 2013-07-23T15:51:21.103 に答える
4

Snap.svg を使用して SVG にクラスを追加します。

var jimmy = Snap(" .jimmy ")

jimmy.addClass("exampleClass");

http://snapsvg.io/docs/#Element.addClass

于 2015-12-07T21:16:43.633 に答える
3

これは、次の問題を処理する (依存関係なしで) かなり洗練されていませんが、機能するコードです。

  • classList<svg>IE の要素に存在しない
  • classNameIE の要素のclass属性を表していない<svg>
  • 古い IE の壊れgetAttribute()setAttribute()実装

可能な限り使用classListします。

コード:

var classNameContainsClass = function(fullClassName, className) {
    return !!fullClassName &&
           new RegExp("(?:^|\\s)" + className + "(?:\\s|$)").test(fullClassName);
};

var hasClass = function(el, className) {
    if (el.nodeType !== 1) {
        return false;
    }
    if (typeof el.classList == "object") {
        return (el.nodeType == 1) && el.classList.contains(className);
    } else {
        var classNameSupported = (typeof el.className == "string");
        var elClass = classNameSupported ? el.className : el.getAttribute("class");
        return classNameContainsClass(elClass, className);
    }
};

var addClass = function(el, className) {
    if (el.nodeType !== 1) {
        return;
    }
    if (typeof el.classList == "object") {
        el.classList.add(className);
    } else {
        var classNameSupported = (typeof el.className == "string");
        var elClass = classNameSupported ?
            el.className : el.getAttribute("class");
        if (elClass) {
            if (!classNameContainsClass(elClass, className)) {
                elClass += " " + className;
            }
        } else {
            elClass = className;
        }
        if (classNameSupported) {
            el.className = elClass;
        } else {
            el.setAttribute("class", elClass);
        }
    }
};

var removeClass = (function() {
    function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {
        return (whiteSpaceBefore && whiteSpaceAfter) ? " " : "";
    }

    return function(el, className) {
        if (el.nodeType !== 1) {
            return;
        }
        if (typeof el.classList == "object") {
            el.classList.remove(className);
        } else {
            var classNameSupported = (typeof el.className == "string");
            var elClass = classNameSupported ?
                el.className : el.getAttribute("class");
            elClass = elClass.replace(new RegExp("(^|\\s)" + className + "(\\s|$)"), replacer);
            if (classNameSupported) {
                el.className = elClass;
            } else {
                el.setAttribute("class", elClass);
            }
        }
    }; //added semicolon here
})();

使用例:

var el = document.getElementById("someId");
if (hasClass(el, "someClass")) {
    removeClass(el, "someClass");
}
addClass(el, "someOtherClass");
于 2015-02-11T11:55:08.873 に答える
1

1 つの回避策は、addClass を svg 要素のコンテナーに追加することです。

$('.svg-container').addClass('svg-red');
.svg-red svg circle{
    fill: #ED3F32;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="svg-container">
  <svg height="40" width="40">
      <circle cx="20" cy="20" r="20"/>
  </svg>
</div>

于 2016-08-20T14:21:42.727 に答える
-1

または、JQ の中間に猿がいる場合は、昔ながらの DOM メソッドを使用します。

var myElement = $('#my_element')[0];
var myElClass = myElement.getAttribute('class').split(/\s+/g);
//splits class into an array based on 1+ white space characters

myElClass.push('new_class');

myElement.setAttribute('class', myElClass.join(' '));

//$(myElement) to return to JQ wrapper-land

DOM の人々を学びましょう。2016 年のフレームワーク palooza でも、かなり定期的に役立ちます。また、誰かが DOM をアセンブリと比較しているのを聞いたことがあれば、私のために蹴ってください。

于 2016-12-19T23:44:16.043 に答える