H2Databaseを追っかけていたりしたブログ

H2 database のリリースノートを読んだりとか。

Dojoのモジュールについて 3 dojo/dom-attr

dojo/dom-attr

dojo/dom-attrはDOMの属性を操作するためのAPIを定義しています。dojo内では、domAttrという名前で使っている事が多いようです。

get/getNodeProp

どちらも指定したDOMの属性を取得できます。何が違うかと言うと、getは明示的に設定された属性値のみが取得でき、getNodePropは明示的に設定されていなくてもデフォルト値がある場合はそれを取得します。

そもそも属性が存在しない場合はどちらの関数もnullが返ります。

引数説明
string/domNode属性値を取得したいdomNodeもしくはそのId
string属性名

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Tutorial: Hello Dojo!</title>
  </head>
  <body>
    <div id="a1">
      <div id="b1">
        <input id="c1" type="text" value="c1:明示的にtype=textを指定">
      </div>
      <div id="b2">
        <input id="c2" data-hoge="hogevalue" value="c2:typeは指定していない">
      </div>
    </div>
    <script src="dojo/dojo.js"
      data-dojo-config="async: true"></script>
    <script>
      require(['dojo/dom','dojo/dom-attr','dojo/domReady!'], function(dom,domAttr){
        console.log('明示的に設定した属性値');
        console.log('domAttr.get("c1","type")',domAttr.get('c1','type'));
        console.log('domAttr.getNodeProp("c1","type")',domAttr.getNodeProp('c1','type'));
        console.log('明示的には設定していない属性値');
        console.log('domAttr.get("c2","type")',domAttr.get('c2','type'));
        console.log('domAttr.getNodeProp("c2","type")',domAttr.getNodeProp('c2','type'));
        console.log('存在していない属性値');
        console.log('domAttr.get("c2","xhoge")',domAttr.get('c2','xhoge'));
        console.log('domAttr.getNodeProp("c2","xhoge")',domAttr.getNodeProp('c2','xhoge'));
        console.log('独自データ属性値');
        console.log('domAttr.get("c2","data-hoge")',domAttr.get('c2','data-hoge'));
        console.log('domAttr.getNodeProp("c2","data-hoge")',domAttr.getNodeProp('c2','data-hoge'));
      });
    </script>
  </body>
</html>

結果。

明示的に設定した属性値
domAttr.get("c1","type") text
domAttr.getNodeProp("c1","type") text
明示的には設定していない属性値
domAttr.get("c2","type") null
domAttr.getNodeProp("c2","type") text
存在していない属性値
domAttr.get("c2","xhoge") null 
domAttr.getNodeProp("c2","xhoge") null 
独自データ属性値 
domAttr.get("c2","data-hoge") hogevalue 
domAttr.getNodeProp("c2","data-hoge") hogevalue
has

属性が明示的に設定されているかチェックします。設定されている場合trueが返り、それ以外の場合はfalseっぽい値が返ります(実際のところnull)

あくまで明示的に属性が設定されているか、というチェックなので、デフォルト値が存在するような属性であっても明示的に設定されていない場合はfalseっぽい値になります。

引数説明
string/domNode属性があるかを確認したいdomNodeもしくはそのId
string属性名

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Tutorial: Hello Dojo!</title>
  </head>
  <body>
    <div id="b2">
      <input id="c2" data-hoge="hogevalue" value="c2:typeは指定していない">
    </div>
    <script src="dojo/dojo.js"
      data-dojo-config="async: true"></script>
    <script>
      require(['dojo/dom','dojo/dom-attr','dojo/domReady!'], function(dom,domAttr){
        console.log("明示的にある属性");
        console.log("id",domAttr.has('c2','id'));
        console.log("明示的にはない属性");
        console.log("type",domAttr.has('c2','type'));
        console.log("存在しない属性");
        console.log("hoge",domAttr.has('c2','hoge'));
        console.log("独自データ属性");
        console.log("data-hoge",domAttr.has('c2','data-hoge'));
      });
    </script>
  </body>
</html>

結果。

明示的にある属性
id true
明示的にはない属性
type null
存在しない属性
hoge null
独自データ属性
data-hoge true 
set

Dom nodeに対して、属性をセットするための関数です。セットするだけと言えばだけですが、3点ほど特筆すべき点があります。

引数説明
string/domNode属性を設定したいdomNodeもしくはそのId
string/object設定したい属性名。もしくは、名前と値のオブジェクト
string/object設定したい値

domAttr.set('node','class','hogeclass');という感じで対象のノードの指定した属性に対して値をセットします。まぁ、これは、思った通りです。で、まず一つ。複数の値を一度にセットしたい場合には、domAttr.set('node',{class: 'hogeclass'});という形でオブジェクトを渡してセットする事が出来ます。

その2。styleをセットしたい場合には、オブジェクトを渡す形でしか設定できません。他の属性値も併せてセットする場合はともかく、styleの設定を行いたい場合については、dom-styleモジュールを使うと良いのではと思います。

その3。値としてfunctionを設定する場合は、デフォルトのハンドラがある場合(formのonsubmitなど)は置き換えにならず、連結される点。その場合、必要に応じて、functionの中でデフォルトのハンドラにイベントが伝播しないようにevent.stop()などで明示的に止めなくてはなりません。

なお、dom-attr経由でリスナとして登録された関数自体は、後から置き換える事が出来ますが、1.8.3では不具合により、この関数経由で登録した一番最初のリスナは置き換えに失敗すると言う不具合があります(下記の例の、divaに対するリスナの設定部分をコメントアウトすると、btnaをクリックしたときの動きが変わるのでわかります。バグレポート済)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script src="dojo/dojo.js"
      data-dojo-config="async: true"></script>
    <script>
      require(['dojo/dom-attr','dojo/domReady!'], function(domAttr){
        domAttr.set('diva','data-test','hogefuga');
        console.log(domAttr.get('diva','data-test'));
        domAttr.set('divb','style',{'color': 'red', border: '1px solid black'});
        domAttr.set('diva',{onclick:function(e){
            console.log('diva');
        }});
        domAttr.set('btna',{onclick:function(e){
            console.log('a1');
        }});
        domAttr.set('btna',{onclick:function(e){
            console.log('a2');
        }});
      });
    </script>
      <div id="diva">TEST</div>
      <div id="divb">TEST</div>
      <button id="btna">button A</button>
  </body>
</html>
remove

引数説明
string/domNode属性を削除したいdomNodeもしくはそのId
string削除したい属性名。

指定した属性をノードから削除します。一部の属性は正規化されます(classNameがclassにhtmlForがforに、tabindexがtabIndexに、readonlyがreadOnlyに。下記サンプルではclassNameを削除すると書いているが実際にはclass属性が削除されます)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <style type="text/css">
      .sample{
        background-color: gray;
        border: 1px solid red;
      }
    </style>
  </head>
  <body>
    <script src="dojo/dojo.js"
      data-dojo-config="async: true"></script>
    <script>
      require(['dojo/dom-attr','dojo/domReady!'], function(domAttr){
        domAttr.set('btna',{onclick:function(e){
            domAttr.remove('diva','className');
        }});
      });
    </script>
      <div id="diva" class="sample">TEST</div>
      <button id="btna">button A</button>
  </body>
</html>