« 要素をクラス名で取得 | メイン | 月を撃て! »

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;
}

投稿者 : 11:42 | コメント (0)

コメント