これまでのところ、私はこれをしなければなりません:
elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");
これはjQueryで実行できますが、このように
$(elem).addClass("first second third");
追加または削除するネイティブの方法があるかどうか知りたいのですが。
これまでのところ、私はこれをしなければなりません:
elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");
これはjQueryで実行できますが、このように
$(elem).addClass("first second third");
追加または削除するネイティブの方法があるかどうか知りたいのですが。
elem.classList.add("first");
elem.classList.add("second");
elem.classList.add("third");
等しい
elem.classList.add("first","second","third");
新しいスプレッド演算子を使用すると、複数のCSSクラスを配列として適用するのがさらに簡単になります。
const list = ['first', 'second', 'third'];
element.classList.add(...list);
あなたは以下のようにすることができます
追加
elem.classList.add("first", "second", "third");
削除する
elem.classList.remove("first", "second", "third");
TLDR;
上記の単純なケースでは、削除が機能するはずです。ただし、削除する場合は、削除する前にクラスが存在することを確認する必要があります
const classes = ["first","second","third"];
classes.forEach(c => {
if (elem.classList.contains(c)) {
element.classList.remove(c);
}
})
このclassList
プロパティは、重複するクラスが要素に不必要に追加されないようにします。この機能を維持するために、ロングハンドバージョンまたはjQueryバージョンが気に入らない場合は、addMany
関数とremoveMany
(DOMTokenList
のタイプclassList
)を追加することをお勧めします。
DOMTokenList.prototype.addMany = function(classes) {
var array = classes.split(' ');
for (var i = 0, length = array.length; i < length; i++) {
this.add(array[i]);
}
}
DOMTokenList.prototype.removeMany = function(classes) {
var array = classes.split(' ');
for (var i = 0, length = array.length; i < length; i++) {
this.remove(array[i]);
}
}
これらは次のように使用できます。
elem.classList.addMany("first second third");
elem.classList.removeMany("first third");
アップデート
コメントによると、定義されていない場合にのみこれらのカスタムメソッドを記述したい場合は、次のことを試してください。
DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function(classes) {...}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function(classes) {...}
のadd()
メソッドでclassList
は、単一の配列ではなく個別の引数を渡すことができるため、applyadd()
を使用して呼び出す必要があります。classList
最初の引数には、同じDOMノードからの参照を渡す必要があり、2番目の引数には、追加するクラスの配列を渡す必要があります。
element.classList.add.apply(
element.classList,
['class-0', 'class-1', 'class-2']
);
これは、IE10および11ユーザーの回避策です。
var elem = document.getElementById('elem');
['first','second','third'].forEach(item => elem.classList.add(item));
<div id="elem">Hello World!</div>
または
var elem = document.getElementById('elem'),
classes = ['first','second','third'];
classes.forEach(function(item) {
elem.classList.add(item);
});
<div id="elem">Hello World!</div>
要素にクラスを追加するには
document.querySelector(elem).className+=' first second third';
アップデート:
クラスを削除する
document.querySelector(elem).className=document.querySelector(elem).className.split(class_to_be_removed).join(" ");
DOMTokenList仕様の新しいバージョンでは、とへの複数の引数、add()
および状態を強制remove()
するための2番目の引数が許可されています。toggle()
執筆時点では、Chromeはとへの複数の引数をサポートしていますが、他のブラウザはサポートしadd()
てremove()
いません。IE 10以下、Firefox 23以下、Chrome 23以下、およびその他のブラウザーは、の2番目の引数をサポートしていませんtoggle()
。
サポートが拡大するまで私を乗り越えるために、次の小さなポリフィルを作成しました。
(function () {
/*global DOMTokenList */
var dummy = document.createElement('div'),
dtp = DOMTokenList.prototype,
toggle = dtp.toggle,
add = dtp.add,
rem = dtp.remove;
dummy.classList.add('class1', 'class2');
// Older versions of the HTMLElement.classList spec didn't allow multiple
// arguments, easy to test for
if (!dummy.classList.contains('class2')) {
dtp.add = function () {
Array.prototype.forEach.call(arguments, add.bind(this));
};
dtp.remove = function () {
Array.prototype.forEach.call(arguments, rem.bind(this));
};
}
// Older versions of the spec didn't have a forcedState argument for
// `toggle` either, test by checking the return value after forcing
if (!dummy.classList.toggle('class1', true)) {
dtp.toggle = function (cls, forcedState) {
if (forcedState === undefined)
return toggle.call(this, cls);
(forcedState ? add : rem).call(this, cls);
return !!forcedState;
};
}
})();
ES5に準拠し、DOMTokenList
期待されている最新のブラウザーですが、このポリフィルをいくつかの特別にターゲットを絞った環境で使用しているため、うまく機能しますが、IE8以下などのレガシーブラウザー環境で実行されるスクリプトを調整する必要がある場合があります。 。
非常にシンプルで派手ではありませんが、私が信じなければならない実用的なソリューションは、非常にクロスブラウザです。
この関数を作成する
function removeAddClasses(classList,removeCollection,addCollection){
for (var i=0;i<removeCollection.length;i++){
classList.remove(removeCollection[i]);
}
for (var i=0;i<addCollection.length;i++){
classList.add(addCollection[i]);
}
}
次のように呼び出します。removeAddClasses(node.classList、arrayToRemove、arrayToAdd);
...ここで、arrayToRemoveは、削除するクラス名の配列です:['myClass1'、'myClass2'] etcetera
...およびarrayToAddは、追加するクラス名の配列です:['myClass3'、'myClass4'] etcetera
標準の定義では、単一のクラスの追加または削除のみが許可されています。いくつかの小さなラッパー関数は、あなたが求めることを実行できます。
function addClasses (el, classes) {
classes = Array.prototype.slice.call (arguments, 1);
console.log (classes);
for (var i = classes.length; i--;) {
classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
for (var j = classes[i].length; j--;)
el.classList.add (classes[i][j]);
}
}
function removeClasses (el, classes) {
classes = Array.prototype.slice.call (arguments, 1);
for (var i = classes.length; i--;) {
classes[i] = classes[i].trim ().split (/\s*,\s*|\s+/);
for (var j = classes[i].length; j--;)
el.classList.remove (classes[i][j]);
}
}
これらのラッパーを使用すると、クラスのリストを個別の引数として、スペースまたはコンマで区切られた項目を含む文字列として、あるいはそれらの組み合わせとして指定できます。例については、http://jsfiddle.net/jstoolsmith/eCqy7を参照してください。
追加するクラスの配列があると仮定すると、ES6スプレッド構文を使用できます。
let classes = ['first', 'second', 'third'];
elem.classList.add(...classes);
文字列内のスペースで区切られた複数のクラスを追加するためのより良い方法は、spread_syntaxをsplitで使用することです。
element.classList.add(...classesStr.split(" "));
@ rich.kellyの回答が気に入りましたが、(コンマ区切りの文字列)と同じ命名法を使用したかったclassList.add()
ので、少しずれています。
DOMTokenList.prototype.addMany = DOMTokenList.prototype.addMany || function() {
for (var i = 0; i < arguments.length; i++) {
this.add(arguments[i]);
}
}
DOMTokenList.prototype.removeMany = DOMTokenList.prototype.removeMany || function() {
for (var i = 0; i < arguments.length; i++) {
this.remove(arguments[i]);
}
}
したがって、次を使用できます。
document.body.classList.addMany('class-one','class-two','class-three');
すべてのブラウザをテストする必要がありますが、これはChromeで機能しました。
存在よりも具体的なものをチェックする必要がありDOMTokenList.prototype.addMany
ますか?classList.add()
IE11で失敗する正確な原因は何ですか?
私は、より現代的でエレガントな方法である非常に単純な方法を見つけました。
const el = document.querySelector('.m-element');
// To toggle
['class1', 'class2'].map((e) => el.classList.toggle(e));
// To add
['class1', 'class2'].map((e) => el.classList.add(e));
// To remove
['class1', 'class2'].map((e) => el.classList.remove(e));
クラス配列を拡張したり、APIから取得したものを簡単に使用したりできるのは良いことです。
最善の解決策の1つは、要素が存在するかどうかを確認してから、追加または場合によっては削除に進み、とりわけ要素が空の場合は削除することです。
/**
* @description detect if obj is an element
* @param {*} obj
* @returns {Boolean}
* @example
* see below
*/
function isElement(obj) {
if (typeof obj !== 'object') {
return false
}
let prototypeStr, prototype
do {
prototype = Object.getPrototypeOf(obj)
// to work in iframe
prototypeStr = Object.prototype.toString.call(prototype)
// '[object Document]' is used to detect document
if (
prototypeStr === '[object Element]' ||
prototypeStr === '[object Document]'
) {
return true
}
obj = prototype
// null is the terminal of object
} while (prototype !== null)
return false
}
/*
* Add multiple class
* addClasses(element,['class1','class2','class3'])
* el: element | document.querySelector(".mydiv");
* classes: passing:: array or string : [] | 'cl1,cl2' | 'cl1 cl2' | 'cl1|cl2'
*/
function addClasses(el, classes) {
classes = Array.prototype.slice.call(arguments, 1);
if ( isElement(el) ){ //if (document.body.contains(el)
for (var i = classes.length; i--;) {
classes[i] = Array.isArray(classes[i]) ? classes[i]: classes[i].trim().split(/\s*,\s*|\s+/);
for (var j = classes[i].length; j--;)
el.classList.add(classes[i][j]);
}
}
}
/*
* Remove multiple class
* Remove attribute class is empty
* addClasses(element,['class1','class2','class3'])
* el: element | document.querySelector(".mydiv");
* classes: passing:: array or string : [] | 'cl1,cl2' | 'cl1 cl2' | 'cl1|cl2'
*/
function removeClasses(el, classes) {
classes = Array.prototype.slice.call(arguments, 1);
if ( isElement(el) ) {
for (var i = classes.length; i--;) {
classes[i] = Array.isArray(classes[i]) ? classes[i]: classes[i].trim().split(/\s*,\s*|\s+/);
for (var j = classes[i].length; j--;)
el.classList.remove(classes[i][j]);
let cl = el.className.trim();
if (!cl){
el.removeAttribute('class');
}
}
}
}
var div = document.createElement("div");
div.id = 'test'; // div.setAttribute("id", "test");
div.textContent = 'The World';
//div.className = 'class';
// possible use: afterend, beforeend
document.body.insertAdjacentElement('beforeend', div);
// Everything written above you can do so:
//document.body.insertAdjacentHTML('beforeend', '<div id="text"></div>');
var el = document.querySelector("#test");
addClasses(el,'one,two,three,four');
removeClasses(el,'two,two,never,other');
el.innerHTML = 'I found: '+el.className;
// return : I found: four three one
#test {
display: inline-block;
border: 1px solid silver;
padding: 10px;
}