Elementオブジェクトは、HTMLまたはXMLの要素を表します。
要素のタグ名は、tagNameプロパティで取得できます。そのタグ名の大文字/小文字は、XMLベースの言語では原型が保たれますが、HTMLではつねに大文字となります。Element.tagName - Web APIs | MDN
var a = document.createElement( 'span' ); alert( a.tagName ); // SPAN alert( a.nodeName ); // SPAN
なお、このプロパティは継承元のNodeではnodeNameというプロパティ名で、同じ値を持ちます。
プロパティ | 内容 | 書き込み ※1 |
---|---|---|
Element. scrollWidth/Height |
要素の大きさ (表示されていない領域を含む) | × |
Element. clientWidth/Height |
要素の表示領域の大きさ (表示領域の大きさ + padding) |
× |
HTMLElement. offsetWidth/Height |
要素の表示領域の大きさ (表示領域の大きさ + padding + スクロールバーの幅 + border) |
× |
※1 大きさはElementのプロパティから変更できないため、styleプロパティのwidthやheightから指定します。
表示される前の要素は、大きさとして0を返します。よって正しい値は、ドキュメントの構築を待ってから取得します。
要素ではなくドキュメントの表示領域の大きさは、ブラウザによって取得方法が異なります。
Width | 値 | Height | 値 |
---|---|---|---|
scrollWidth | scrollHeight | ||
clientWidth | clientHeight | ||
offsetWidth | offsetHeight |
プロパティ | 内容 | 書き込み |
---|---|---|
HTMLElement. offsetLeft / offsetTop |
offsetParent要素に対する、相対的な位置 ※親要素に対する位置ではない |
× |
Element. scrollLeft / scrollTop |
要素の内容がスクロールされた量
scrollLeftの最大値 = scrollWidth - clientWidth |
○ |
要素ではなくドキュメントのスクロール位置は、ブラウザによって取得方法が異なります。
要素のサイズやスクロール位置を変更したときの、プロパティの変化を確認できます。
ボックスの右下にリサイズハンドルが表示されているならば、それをドラッグすることで要素の大きさを変更できます。そのとき下表の値が変わらないならば、スクロールすることで更新されます。
※リストの数値は、親要素からのオフセットWidth | 値 | Height | 値 |
---|---|---|---|
scrollWidth | scrollHeight | ||
clientWidth | clientHeight | ||
offsetWidth | offsetHeight |
Left | 値 | Top | 値 |
---|---|---|---|
offsetLeft | offsetTop | ||
scrollLeft | scrollTop |
scrollLeft、scrollTopは書き込みできるプロパティであり、値を設定すると要素を含むドキュメントがスクロールします。
scrollTopの値を変更すると、下の要素が移動します。
※リストの数値は、親要素からのオフセットnumber.oninput = number.onchange = function() { element.scrollTop = this.value; } element.onscroll = function() { number.value = this.scrollTop; }
要素の親要素を、その要素の上端位置 (親要素との相対位置) までスクロールします。
elem.parentNode.scrollTop = elem.offsetTop - elem.parentNode.offsetTop;
offsetParentは、要素のオフセットの基準となる要素への参照を返します。HTMLではたいていbody要素が返されますが、例外が多くあります。offsetTop/offsetLeft/offsetParentの闇 - Backstage of theater.js
Element.attributesにより、すべての属性をNamedNodeMapインターフェイスとして取得できます。NamedNodeMap - Web API Interfaces | MDN
操作 | メソッド |
---|---|
設定※1 | void setAttribute( String name, String value );element.setAttribute - Web API インターフェイス | MDN |
取得※1 | String getAttribute( String name );element.getAttribute - Web API インターフェイス | MDN |
削除 | void removeAttribute( String name );element.removeAttribute - Web API インターフェイス | MDN |
調査 | boolean hasAttribute( String name );element.hasAttribute - Web API インターフェイス | MDN |
※1 設定と取得のメソッドは、HTMLの非標準の属性を対象とする場合にのみ使用します。標準の属性ならば、次に示すようにプロパティとしてアクセスできます。
var input = document.createElement( 'input' ); // メソッドでアクセス input.setAttribute( 'readOnly', '' ); // <input readonly=""> input.removeAttribute( 'readOnly' ); // <input> // プロパティでアクセス input.readOnly = true; // <input readonly=""> input.readOnly = false; // <input>
次の2つは、同一の属性を設定します。
Element.name = value;
Element.setAttribute( name, value );
setAttribute()で設定するvalueは、つねに文字列です。一方で標準の属性をプロパティで設定するときは、そのプロパティによって型が異なります。
var input = document.createElement( 'input' ); input.setAttribute( 'disabled', 'disabled' ); // true input.setAttribute( 'disabled', 'true' ); // true input.setAttribute( 'disabled', '' ); // true input.setAttribute( 'disabled', 'false' ); // true input.setAttribute( 'disabled', false ); // true input.disabled = false; // false input.removeAttribute( 'disabled' ); // false
また属性が設定される順は、ブラウザによって異なります。
var a = document.createElement( 'a' ); a.setAttribute( 'p1', '' ); a.setAttribute( 'p2', '' ); a.setAttribute( 'p3', '' ); alert( a.outerHTML ); // Internet Explorer 11 … <a p1="" p2="" p3=""></a> // Chrome … <a p1="" p2="" p3=""></a> // Firefox … <a p3="" p2="" p1=""></a>
標準の属性ならば、
var value = Element.name;
とすることで取得できます。一方で非標準の属性はこの方法ではundefinedを返すため、
var value = Element.getAttribute( name );
とします。
属性の内容を削除するだけならば空文字などを代入することで事足りますが、属性自体を削除するにはremoveAttribute()を用います。
var a = document.createElement( 'div' ); var b = document.createElement( 'div' ); a.className = 'A' // <div class="A"></div> b.className = 'B' // <div class="B"></div> a.className = null; // <div class="null"></div> a.className = ''; // <div class=""></div> b.removeAttribute( 'class' ); // <div></div>
innerHTMLプロパティで、要素の内容の取得や設定を行えます。
var markup = element.innerHTML; // 取得 element.innerHTML = markup; // 設定element.innerHTML - Web API インターフェイス | MDN
HTMLのマークアップに使用される文字「&」「<」「>」の3文字をinnerHTMLから取得すると、文字参照の表記として返されます。これをテキストノードの内容と同じに取得するには、代わりにtextContentを使用する必要があります。
var a = document.createElement( 'div' ); a.innerHTML = '& < >'; alert( a.innerHTML ); // & < > alert( a.textContent ); // & < >
なお文字参照でinnerHTMLに設定した場合には、textContentはデコードした結果を返します。
var b = document.createElement( 'div' ); b.innerHTML = '& < >'; alert( b.innerHTML ); // & < > alert( b.textContent ); // & < >
innerHTMLの戻り値を他の要素のinnerHTMLに設定すると、要素の内容をそのまま複製できます。ただしイベントハンドラは複製されません。これはcloneNode()で要素を複製する場合の挙動と同じです。
var link = document.createElement( 'a' ); link.innerHTML = 'Click'; link.onclick = function() { alert( 'OK' ); }; var a = document.createElement( 'span' ); a.appendChild( link ); var b = document.createElement( 'span' ); b.innerHTML = a.innerHTML; document.body.appendChild( a ); document.body.appendChild( b );
複製元の要素に続けて、それを複製した要素を並べて表示します。左の要素はクリックに反応しますが、右の要素はそうはならないはずです。
親要素の子要素、つまり要素自身を書き換えるとハンドラは無効となります。
var parent = document.body.appendChild( document.createElement( 'p' ) ); var link = document.createElement( 'a' ); link.innerHTML = 'Click'; link.onclick = function() { alert( 'OK' ); }; parent.appendChild(link); link.innerHTML += 'A'; // 子要素を書き換えても影響はない parent.innerHTML += 'B'; // 親要素を書き換えるとハンドラは無効となる
さまざまな条件でDOMからElementを取得できます。
オブジェクト | Elementの特定方法 | ||
---|---|---|---|
id属性の値 | name属性の値 | HTMLのタグ名 | |
Document | getElementById | - | - |
HTMLDocument | - | getElementsByName | getElementsByTagName |
Element | - | - |
IE8より前では、このメソッドはname属性も取得対象となっています。
Element[] getElementsByName( string elementName );document.getElementsByName - Web API インターフェイス | MDN
このメソッドが返すElementの配列のようなオブジェクトは、HTMLCollectionです。このオブジェクトは配列のように振る舞いますが、その実体は配列ではないため扱いには注意が必要です。
またgetElementsByName()はHTMLDocumentのメソッドのため、その探索範囲はドキュメント全体となります。
name属性を対象とするため、たとえば
document.getElementsByName( 'description' )
とすれば、meta要素の
<meta name="description" content="" />
が、HTMLMetaElementオブジェクトとして取得できます。
Element[] getElementsByTagName( string tagName );element.getElementsByTagName - Web API インターフェイス | MDN
このメソッドもgetElementsByName()と同様、結果をHTMLCollectionオブジェクトで返します。なおtagNameプロパティはHTMLでは大文字ですが、このメソッドの引数のtagNameは小文字で指定します。
getElementsByTagName()は2つのオブジェクトに実装されています。これらは機能的には同じですが、Elementを探索する範囲が異なります。
これらの違いは探索を開始する位置にあり、いずれにしても子孫の要素まですべて探索されることになります。それを次に例示します。
<div id="foo"> <!-- 探索対象のツリー --> <ul> <li id="a"></li> <li id="b"> <ul> <li id="c"></li> </ul> </li> </ul> </div> <script type="text/javascript"> var target = document.getElementById( 'foo' ); var tag = target.getElementsByTagName( 'li' ); // HTMLCollection[li#a, li#b, li#c] </script>
これを直接の子供の要素にだけ限定するには、Nodeオブジェクトのプロパティを参照します。
HTMLDocumentには、ドキュメント内の特定のすべての要素を格納するプロパティが用意されています。該当するプロパティがあるならば、こちらを使用する方が簡単です。
以下のメソッドにより、イベントハンドラの追加や削除を行えます。
操作 | メソッド |
---|---|
追加 |
void addEventListener( String type, Function listener, boolean useCapture ); |
削除 |
void removeEventListener( String type, Function listener, boolean useCapture ); |
発生 | boolean dispatchEvent( Event evt ); |
Internet Explorerでは上記のメソッドが使用できないため、以下のもので代替します。
操作 | メソッド |
---|---|
追加 | void attachEvent( String type, Function listener ); |
削除 | void detachEvent( String type, Function listener ); |
これをクロスブラウザとするためには、実装されているメソッドを確認して使用することになります。