タグの属性値を操るDOMの基本を学ぼう(5)(2/3 ページ)

» 2008年06月05日 00時00分 公開
[羽田野太巳@IT]

getAttribute/setAttributeメソッドによる操作

 DOMでは、タグの属性を読み取ったり書き込んだりするインタフェースとして、プロパティだけではなく、メソッドも提供しています。読み取るときにはgetAttributeを、書き込むときにはsetAttributeメソッドを使います。プロパティによるインタフェースはHTMLのためだけに規定されたものですが、メソッドによるインタフェースは、もともとXMLのために規定されたものです。しかし、HTMLにおいても活用できます。

 getAttributeメソッドは引数に属性名を与えます。setAttributeメソッドは2つの引数を与えますが、1つ目に属性名を、2つ目に変更したい値をセットします。

anchor_uri_method.html
<a href="http://www.w3.org/" id="link">W3C</a>
<script type="text/javascript">
  /*Aタグの要素オブジェクト*/
  var link = document.getElementById('link');
  /*href属性値*/
  var uri = link.getAttribute('href');
  /*アラートウィンドウに表示*/
  alert(uri);
  /*URIを書き換える*/
  link.setAttribute('href', 'http://www.sbcr.jp/');
</script>

 このサンプルは前節と同じものですが、属性値の読み取りと書き込み時に、getAttributeメソッドとsetAttributeメソッドを使っている点が異なります。

 先ほど、属性プロパティを使ってclass属性を書き換える場合、プロパティ名は"class"ではなく"className"になることを学んできました。getAttribute/setAttributeメソッドでは、本来はこの制限が適用されないはずです。つまり、class属性名に"class"と指定すれば動作するはずです。ところが、Internet ExplorerはDOMの規定通りには動作しません。

 getAttribute/setAttributeメソッドに対しても"className"と指定しないと動作しないのです。当然のことながら、Firefox、Opera、Safariでは、getAttribute/setAttributeメソッドに"className"と指定しても正しく動作しません。クロスブラウザ対策として、getAttribute/setAttributeメソッドを使ってclass属性を操作したい場合は、"class"と"className"の両方を指定します。

 先のclass_property.htmlで使った、ボタンを押してスタイルを切り替えるサンプルを、setAttributeメソッドを使う方法に書き換えてみましょう。

class_setAttribute.html
<style type="text/css">
  #box { width: 150px; height:80px; border: 1px solid #4c4c4c; padding:
  12px; text-align: center; }
  .red { background-color: #ff0000; }
  .gray { background-color: #cccccc; }
</style>
<div id="box" class="gray">
  <div>ボタンを押すと、ボックスの背景色が変わります。</div>
  <div><input type="button" name="btn" value="背景色変更"
 onclick="classChange()" /></div>
</div>
<script type="text/javascript">
 function classChange() {
  /*本来の書き方*/
  document.getElementById('box').setAttribute('class', 'red');
  /*Internet Explorer用*/
  document.getElementById('box').setAttribute('className', 'red');
 }
</script>

 class属性を変更する処理を、本来の書き方と、Internet Explorer用の書き方の両方で記述している点に注目してください。

 DOMでは、属性プロパティがタグ要素ごとに規定されていることを説明しましたが、DOMで規定されていないプロパティを強引に使ったとしてもエラーにはなりません。同様にgetAttribute/setAttributeメソッドでも、JavaScriptエラーにはなりません。そして多くのブラウザで、期待通りの挙動を示します。しかし、これはあくまでも各ブラウザが独自に実装したか、もしくはたまたま動作してしまっているだけの可能性が高いと言えます。基本的に、DOMで規定されていないプロパティを使うことは避けた方がよいでしょう。よくあるトラブルに、style属性やイベントハンドラーがあげられます。

setAttribute_ng.html
<input type="button" name="btn" value="set" id="btn" />
<script type="text/javascript">
 /*ボタンの要素オブジェクト*/
 var btn = document.getElementById('btn');
 /*style属性をセットする*/
 btn.setAttribute('style', 'color: red');
 /*onclick属性をセットする*/
 btn.setAttribute('onclick', 'alertPopup()');
 function alertPopup() {
  alert('OK');
 }
</script>

 このHTMLをブラウザでアクセスすると、ボタン内の「set」という文字が赤色になるはずです。ボタンを押せば、「OK」と表示されたアラートウィンドウがポップアップすると期待するでしょう。多くのメジャーなブラウザでは期待通りの結果が得られます。しかしInternet Explorerでは、期待外れの結果に終わります。

 このように本来、DOMで定義されていないプロパティをsetAttributeメソッドで使うと、予期せぬ挙動に直面します。スタイルの操作方法、イベントのハンドリング方法に関しては、DOMで別途規定されています。

 確かにInternet Explorerは、他の主要なブラウザと比べてDOMの実装が遅れていたり、挙動がおかしい点がいくつかあります。このサンプルが動作したブラウザは、DOMの規定に沿った挙動ではなく、ブラウザ独自に組み込まれた機能によって動作したといえます。そのため、style属性やイベントハンドラーに限定すれば、Internet Explorerが悪いと烙印を押すのは酷かもしれません。しかし、多くの人が直感する通りの挙動をしないというのは、ユーザーフレンドリー(デベロッパーフレンドリー?)ではないことは確かでしょう。

 話がそれてしまいましたが、DOMで規定されているスタイルの扱い方やイベントハンドリング手法については、のちほど詳しく解説します。DOMにとらわれる必要がなければ、現段階ではとりあえず、次のようにスクリプトを書き換えることで期待通りの挙動を示すようになります。

setAttribute_ok.html
<input type="button" name="btn" value="set" id="btn" />
<script type="text/javascript">
 /*ボタンの要素オブジェクト*/
 var btn = document.getElementById('btn');
 /*style属性をセットする*/
 btn.style.color = 'red';
 /*onclick属性をセットする*/
 btn.onclick = alertPopup;
 function alertPopup() {
  alert('OK');
 }
</script>

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。