HTMLElement.value の代わりに、innerHTML または textContent を使う
特定のIDの値によって振る舞いが変化する拡張機能をつくろうとして、
getElementById の value が undefined になり困り果てた。
- タブ更新時
- URL に 'yahoo' を含む場合、pageAction アイコンを表示
- pageAction アイコンをクリック時
- Yahoo! トップページの HTML を取得
- DOMParser から Document オブジェクトを生成
- a タグ id="msearch" の値を取得したい(←ここ)
結論
- value の代わりに、innerHTML または textContent を使う。
- innerText より textContent を使ったほうがよい。
JavaScriptのDOM操作の基本がわかっていなかっただけの話。
説明
background.js
// https://developer.chrome.com/extensions/tabs#event-onUpdated chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if (tab.url.indexOf('yahoo') != -1) { // https://developer.chrome.com/extensions/pageAction#method-show chrome.pageAction.show(tabId); } }); // https://developer.chrome.com/extensions/pageAction#event-onClicked chrome.pageAction.onClicked.addListener(function() { // https://developer.chrome.com/extensions/tabs#method-executeScript chrome.tabs.executeScript(null, { "code": "document.all[0].outerHTML" }, function(result) { var doc = new DOMParser().parseFromString(result, 'text/html'); var elem = doc.getElementById('msearch'); console.log('elem: ' + elem); console.log('elem.innerHTML: ' + elem.innerHTML); console.log('elem.innerText: ' + elem.innerText); console.log('elem.textContent: ' + elem.textContent); console.log('elem.toString: ' + elem.toString()); console.log('elem.value: ' + elem.value); }) });
background のコンソール
Aタグの取得には成功していた。
elem: <a href="http://rdsig.yahoo.co.jp/_ylt=A3xTym7Gx2ZWTxgA16KJBtF7/RV=1/RE=1449662790/RH=cmRzaWcueWFob28uY28uanA-/RB=9c2YVaHx1cTZXkzhCTjIC81xGhM-/RU=aHR0cDovL3NlYXJjaC55YWhvby5jby5qcC92aWRlbw--/RS=^ADAgbmRCkcMzdw3i8M0MnKTRz_Ds9A-" id="msearch" hidefocus="true">動画</a>
innerHTML と innterText と textContent に値が入っていた。
elem.innerHTML: 動画
elem.innerText: 動画
elem.textContent: 動画
toString すると、href が返ってきた。
elem.toString: http://rdsig.yahoo.co.jp/_ylt=A3xTym7Gx2ZWTxgA16KJBtF7/RV=1/RE=1449662790/RH=cmRzaWcueWFob28uY28uanA-/RB=9c2YVaHx1cTZXkzhCTjIC81xGhM-/RU=aHR0cDovL3NlYXJjaC55YWhvby5jby5qcC92aWRlbw--/RS=^ADAgbmRCkcMzdw3i8M0MnKTRz_Ds9A-
value は undefined になった。
elem.value: undefined
なぜこのような結果になるのか
A タグの実体は HTMLAnchorElement
HTMLAnchorElement は HTMLElement を継承
HTMLElement は Node を継承
HTMLElement.innerHTML の記事に次の記載がある。
このプロパティには公式な仕様が無いため、各実装には大きな隔たりがあります。例えば、テキスト入力欄 (HTML の input 要素など) にテキストが入力された場合、IE は input の innerHTML プロパティの value 属性を変更しますが、Gecko ブラウザは変更しません。
Node.textContent に「textContent と innerText の違い」が熱弁されている。
読むとわかるので割愛するが、innerText ではなく、textContent を使ったほうがよい。
参考記事
本文中に記載