Jintrick.netagenda2007年11月アーカイブ → 2007年11月26日

クラス名を操作するchangeClassメソッド

過去の記事を見直していて、6年も前の話だけれど複数クラスとDOM (agenda)が見過ごせないほど酷いので訂正。

要素のclass属性値を判別したかったらしいのだが、className属性の値の型を「実験」で確認した挙句、こんな結論にしてしまっている:

クラス名で判別する時は、一つしかなくとも*.className.indexOf('クラス名') != -1 で。

これでは同じ文字列を含む異なるクラス名を混同してしまう。私が現在使用しているクラス名の判別、変更及び削除用のメソッドを公開しておこう(注:Javascript1.6以上が要求される)。

code1. getterとsetterを定義

Element.prototype.__defineGetter__("klass",
    function(){
        return this.className.split(/\s/))
    }
);
Element.prototype.__defineSetter__("klass",
    function(ary){
        this.__klass = ary;
        try {
            this.className = ary.length && ary.join(" ") || "";
        } catch(e) {
            throw new TypeError("TypeError. Element.klass property must be an array.");
        }
    }
);

code1. はelement.klass でクラス名の配列をgetできるようにしており、またelement.klass = で値(クラス名の配列)をセットできるようにしている。

elementは任意の要素オブジェクトの参照である。class属性のない要素でも、classNameプロパティにはlengthが0の文字列が格納されている為、klassプロパティはlengthが0の文字列が一つ格納されたArrayオブジェクトになる。

これで、element.klass.indexOf("クラス名") = -1 というコードでクラスの判別ができるようにはなったし、element.klass = element.klass.concat(クラス名) というコードでクラス名の追加ができるようにはなった。しかしながら、クラス名の変更削除には配列の操作をしなければならず、配列という「インターフェイス」を被せてその操作を行うことでクラス名の操作を行っているため、セマンティックではない。

code2. クラス判別用メソッド
Element.prototype.isClassOf = function(name){
    return this.klass.indexOf(name) != -1;
};

code2. はクラス判別用のメソッド、isClassOfをElementプロトタイプに追加している。これでElementのインスタンス全てがisClassOfメソッドを使用可能となる。本来はHTMLElementという、HTMLの「名前空間」に属するオブジェクトのプロトタイプに追加すべきであるが、そもそもclassNameアトリビュートはDOM1 HTMLで定義されていて、DOM コアには含まれないものであり、XMLとして処理されるXHTMLでは未定義である。

code3. 追加、変更、削除用メソッド 「changeClass」を定義
Element.prototype.changeClass = function(newClass, oldClass){
    var klass = this.klass;
    if (!newClass && !oldClass)
        klass = [];
    else if (!oldClass)
        this.isClassOf(newClass) || klass.push(newClass);
    else if (!newClass)
        this.isClassOf(oldClass) && klass.splice(klass.indexOf(oldClass), 1);
    else
        klass.splice(klass.indexOf(oldClass), 1, newClass);
    this.klass = klass;
};

code3. はクラス名の追加、変更、削除を一手に担う changeClassメソッドをElementプロトタイプに追加している。これで、Elementのインスタンスは全て、changeClassというメソッドを通じてセマンティックにクラス名を操作可能となる。使用例は次のcode4. のようになる。

code4. 使用例
var e = document.body;
// BODY要素を例として:

e.changeClass("new", "old");
// クラス名の中に"old"があれば"new"に変える

e.changeClass("new")
// クラス名に"new"を加える(既存なら何も起こらない)

e.changeClass(null, "old")
// クラス名に"old"があれば、それを削除する

e.changeClass(null)
// 全てのクラス名を削除する

要するに、追加したいクラス名はchangeClassメソッドの第一引数に指定し、削除したいクラス名はchangeClassメソッドの第二引数に指定する。


webmaster@jintrick.net
公開: 2007年11月26日
カテゴリ: DOM ,Javascript