ツール開発講座 〜第9回 getElement・・・〜 | 元溥帝のまったりブログ

元溥帝のまったりブログ

ブラウザ三国志 溥帝○○翼賛会の公式ブログのようです。

今回は
getElementById()
getElementsByClassName()
getElementsByTagName()
という3つの要素取得方法を紹介します。


■getElementById()

指定したid属性を持つ要素を取得します。

例えば、サーバー時間を取得してみます。
サーバー時間のところで右クリック→Firebugで要素を調査。
<span id="server_time_disp">21:32:04</span>
って感じのが見えるかと思います。
spanタグで要素が作られてて、id属性が"server_time_disp"となっています。

var hogehoge = document.getElementById("server_time_disp")

これでサーバー時間の要素が取得出来ました。
あとはXPathで取得した時と同じように
hogehoge.textContent
とかすれば、サーバー時間のテキストが取得できます。


■getElementsByClassName()


今度はclass属性で取得します。
getElementsと複数形になっていることに注意してください。
idは一つって決まってるんですが、classは複数ある可能性があるので、複数形なんです。

例えば、同盟ランクの表を先ほどと同じようにFirebugで調査すると
<table class="tables" summary="ランキング">
こんな感じになっています。

同盟ランクの表はtableタグによって作られてて、class属性は"tables"のようです。

var hogehoge = document.getElementsByClassName("tables")

これでclassが"tables"の要素の集合を取得出来ました。
一つの要素に絞りたい場合はclass名が"tables"の要素の中で何番目の要素かを指定してやる必要があります。
順番は0番から始まります。

最初の要素を取得したかったら
hogehoge[0]
となります。

document.getElementsByClassName("tables")[0]
って書いても構いません。

そんな事言ったって、目的の要素が何番目かをどうやって知ればいいんじゃい!?
ってなりますよね。
ページのソースを全部読むのは大変です。

そんな時はこのようにしてやります。

Firebugで要素を調査すると、目的のclass"tables"の要素の先祖に"gray02Wrapper"というidを持った要素がいるのが見つけられるでしょうか?

そこでまずid"gray02Wrapper"の要素を取得して、
var hogehoge = document.getElementById("gray02Wrapper")

そこの中でclassを指定してやる事ができます。
var hoge = hogehoge.getElementsByClassName("tables")

これだったら、目的の要素が最初のclass"tables"ってすぐにわかりますね。
hoge[0].style.backgroundColor = "yellow"
とかしてやれば、この表の背景色が黄色になるかと思います。


■getElementsByTagName()

タグ名で取得したい時に使います。
使い方はclassの時と一緒。

今回はこれを使って、ツールを作っていきます(今まで作ってきたツールを書き換えていきます)。

最初に自分の名前を書いておきます。
var myName = "ぷり☆けつ"
ここは今までと同じですね。

XPathでの取得を学習してきた皆さんは、同盟ランクの各行がtrタグで作られていることを既にご存知かと思います。
そこでtrタグの要素を全部取得してきます。
var tr = document.getElementsByTagName("tr")

これでも良いのですが、せっかくidやclassでの取得もやりましたので、もうちょっと絞り込んで取得してみましょうか。
var gray02Wrapper = document.getElementById("gray02Wrapper")
var tables = gray02Wrapper.getElementsByClassName("tables")[0]
var tr = tables.getElementsByTagName("tr")

さて、getElements~で取得した要素の数はlengthで知ることができます。
var len = tr.length
これで何個trがtablesにあるかがわかります。

全てのtrに対してmyNameと同じ文字列があるか調べたいのでforループを使います。
for (var i=0; i<len; i++){
}

forループの中身を考えます。
ユーザー名はaタグの中に書いてあるので
var target = tr[i].getElementsByTagName("a")[0]
var userName = target.textContent

このuserNameとmyNameが同じだった時にtrを黄色くしたいから
if (userName==myName){
 tr[i].style.backgroundColor = "yellow"
 break
}

全体像
// ==UserScript==
// @name bro3-HighLightName
// @namespace http://ameblo.jp/putei1724
// @include http://*.3gokushi.jp/alliance/info.php*
// @version 1
// @grant none
// ==/UserScript==

var myName = "ぷり☆けつ"

var gray02Wrapper = document.getElementById("gray02Wrapper")
var tables = gray02Wrapper.getElementsByClassName("tables")[0]
var tr = tables.getElementsByTagName("tr")
var len = tr.length

for (var i=0;i<len;i++){
 var target = tr[i].getElementsByTagName("a")[0]
 var userName = target.textContent

 if (myName==userName){
  tr[i].style.backgroundColor = "yellow"
  break
 }
}

これで行けそうです。

走らせてみます。

・・・ありゃ?黄色くならないw
よくあることですwめげずにCtrl+Shift+Jを押してみてください。



target is undefined
なんてエラーが出ています。

targetなんて無ぇよって言われています。

今回全てのtrに関してtargetを取得しようとしました。
しかしtrの中にはtarget(aタグ)が無いtrもあります。


最初と2番目のtrにはaタグはありませんね。

そこでこんなのを噛ませてやります。
if (target == undefined){
 continue
}
これは、targetがundefinedだったら(if文)、
ループ内処理をここでやめて、次のループに行きなさい(continue)
という意味です。

continueはbreakと似ていますが、違いをしっかりおさえてください。
breakではそこでループ中断。
continueではループのその回を飛ばす。


さて全体像です。
// ==UserScript==
// @name bro3-HighLightName
// @namespace http://ameblo.jp/putei1724
// @include http://*.3gokushi.jp/alliance/info.php*
// @version 1
// @grant none
// ==/UserScript==

var myName = "ぷり☆けつ"

var gray02Wrapper = document.getElementById("gray02Wrapper")
var tables = gray02Wrapper.getElementsByClassName("tables")[0]
var tr = tables.getElementsByTagName("tr")
var len = tr.length

for (var i=0;i<len;i++){
 var target = tr[i].getElementsByTagName("a")[0]

 if (target == undefined){
  continue
 }
 
 var userName = target.textContent
 
 if (myName==userName){
  tr[i].style.backgroundColor = "yellow"
  break
 }
}

これならちゃんと動きました♪


今回は今までとは違う方法で要素を取得してみましたが、いかがだったでしょうか?

最初の頃に比べて、だいぶレベルを上げているので、ついてこれなくなっている方も多いかもしれません。
そこで、ここで一旦中断し、皆さんからの声を待ちたいと思います。

その反響によって、補講を何回かやるか、さらに連載を進めるか、はたまた連載打ち切りとするか、判断したいと思います。