概要
getElementById()等で要素ノードにアクセスできたら、次は、その要素ノードに何らかの処理をしたい。
特定の属性の取得
多くの属性は「要素ノードの同名のプロパティ」としてアクセスできるからです。たとえば、
//取得
let url = link.href
//設定
link.href = 'https://google.com'
ただし、classに関してはclassNameになることが注意点です。この「属性とプロパティは一致しない場合がある」ことを意識したくないのであれば、次の方法がある。
elem.getAttribute(name)
elem.setAttribute(name, value)
//elem : 要素オブジェクト name : 属性名 value : 属性値
これを用いて書き直すと、
let url = link.getAttribute('href')
link.setAttribute('href', 'https://yahoo.com')
getAttributeとsetAttributeを使うメリットとしては、
1. HTMLとjavascriptとで名前の相違を意識する必要はない。
2. (文字列として指定できるため)取得/設定する属性名を、スクリプトから動的に変更できる。
が挙げられる。
不特定の属性の所得
一つ一つ属性を取得するのではなく、ある特定の要素ノードに属する属性値をすべて取得したい場合はAttributesをつかう。例えば、
<img id="logo" src="https://sample.to/image/1.png" height="57" width="10" alt="image" />
document.addEventListener('DOMContentLoaded', function(){
let logo = document.getElementById('logo')
let attrs = logo.attributes
for(let i = 0, let len = attrs.length: i < len; i++){
let attr = attrs.item(i)
//nameとvalueプロパティでアクセス。
console.log(attr.name + ',' + attr.value)
}
}, false)
//出力
id:logo
src:https://sample.to/image/1.png
height:57
width:10
alt:image
取り出した属性ノードの名前や値にアクセスするには、name/valueプロパティを使う。この例で使われている attrs はNamedNodeMapオブジェクトと呼ばれ、この属性値のマップを操作することも可能。次のように、
//title属性を作成
let title = document.createAttribute('tilte')
title.value = 'ロゴ画像'
//マップに追加と削除
attrs.setNamedItem(title)
attrs.removeNamedItem(title)
テキストの取得/設定
要素配下のテキストを取得/設定するには、innerHTML / textContentというプロパティを利用する。
<div id="result_text">
<p style="color: red;">設定されていません!</p>
</div>
<div id="result_html">
<p style="color: red;">設定されていません!</p>
</div>
document.addEventListener('DOMContentLoaded', function() {
documentGetElementById('result_text').textContent =
'<a href="https://google.com">Google</a>'
documentGetElementById('result_html').innerHTML =
'<a href="https://yahoo.com">yahoo</a>'
}, false)
これで重要なことは、「配下の子要素/テキストを完全に書き換えている」ということです。しかし、決定的に違うところは、「与えられたテキストをHTMLとして認識するかどうか」である。一般的には、textContentプロパティを優先して利用することで、高速かつ安全に運用できる。
また、console.log()ではinnerHTMLプロパティはHTML文字列すべてを返すが、textContentはその中のテキストだけを取り出して出力することに注意する。
innerHTMLの注意点
innerHTMLプロパティを利用する場合、ユーザからの入力値をはじめ、外部からの入力値をそのまま渡さないようにしなければならない。
<form>
<label for="name">名前:</label>
<input id="name" name="name" type="text" />
<input id="btn" type="button" value="送信" />
</form>
<div id="result"></div>
document.addEventListener('DOMContentLoaded', function() {
let name = document.getElementById('name')
let result = document.getElementById('result')
//この文が問題の文!
result.innerHTML = 'こんにちは、' + name.value + 'さん!'
})
result.innerHTMLの文が好ましくないところである。なぜならば、innerNTMLはHTML認識可能な文を第三者が入力可能であるため、製作者が意図しないコードを入力してくる可能性がある。しかもそれを不特定多数の人がブラウザー上で実行することができるのである。このような脆弱性をクロスサイトスクリプティング(XSS)脆弱性という。innerHTMLではなくtextContentにすることが望ましい。
参考資料
山田祥寛様 「javascript本格入門」