« 要素をクラス名で取得 | メイン | 月を撃て! »
2005年06月09日
正しいクラス名の取得方法 [DOM]
先ほどの記事(要素をクラス名で取得)であげたコードは、実は完璧ではない。こんなケースに対応できないからだ。
<input type="text" class="int users" />
class属性は、空白で区切った複数のクラス名を割り当てることができる。上記の例では int のほかに、users という別のクラスにも属していることがわかる。
こうなると、単純な == 比較演算子による判別はできない。String.match ならどうだろう。うまく正規表現を行えばそれでもよいが、編集についても考えるならば多少複雑でも String.split メソッドを使うのがよりベターだ。
JScriptで実装するとしたら、次のようになるだろう
// クラス名が含まれるか判別
// 引数:対象ノード, クラス名
// 返値:-1 = ない; 0以上 = 見つかった場所(一番左を0とする)
function isClassName(argNode, argClassName){
if(argNode.className != ""){
var aryClassName = String(argNode.className).split(" ");
for(i=0; i<aryClassName.length; i++){
if(aryClassName[i] == argClassName){ return i; }
}
}
return -1; // 見つからなければ -1 を返す
}
これはクラス名の追加や削除にも言えることである。単純に代入するだけでは、他のクラス名までも上書きしてしまう恐れがある。追加はこんな感じになるだろうか。
// クラス名を追加
// 引数:対象ノード, クラス名
// 返値:0 = 追加した; 1 = すでにある
function addClassName(argNode, argClassName){
if(isClassName(argNode, argClassName) != "-1"){
return 1; // すでにある場合は無視
}
// 空白とともに追加
argNode.className += " " + argClassName;
return 0;
}
同じように、削除も作ってみた
// クラス名を削除
// 引数:対象ノード, クラス名
// 返値:0 = 存在しない; 1 = 削除した
function removeClassName(argNode, argClassName){
var classIndex = isClassName(argNode, argClassName);
if(classIndex == -1){ return 0; } // なければ無視
var aryClassName = String(argNode.className).split(" ");
aryClassName.splice(classIndex, 1); // 削除
argNode.className = aryClassName.join(" ");
return 1;
}