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 を使ったほうがよい。

参考記事

本文中に記載

関連記事

エレメントの値を取得する方法