VBAでIEを操る(ページ移動後にDOMや要素を再取得しなかったらどうなるのか?)
今回は、変数に取得したDOMや要素が、ページ移動後、どんな挙動になるか調べてみます。
ページを移動した後、DOMツリー構造が変わるので、再取得する必要があるだろう・・・・・・と予想できます。が、実際はどうなのか、書籍やネットから腑に落ちる情報を見つけられなかったので、実験してみます。
目次
- 要素ひとつを変数に取得し、ページ移動後、再取得せずに使用した場合
- 要素ひとつを変数に取得し、ページ移動後、再取得した場合
- 同じ要素すべてを変数に取得し、ページ移動後、再取得せずに使用した場合
- 同じ要素すべてを変数に取得し、ページ移動後、再取得した場合
- IDで指定した要素を変数に取得し、ページ移動後、再取得せずに使用した場合
- IDで指定した要素を変数に取得し、ページ移動後、再取得した場合
- documentプロパティでDOMを変数に取得し、ページ移動後、再取得せずに使用した場合
- documentプロパティでDOMを変数に取得し、ページ移動後、再取得した場合
- まとめ
実験に使うのは、以下のHTML文書です。
ページ移動前
↑このページのソース
<html>
<body>
<p id="ichibanjukusita">りんご</p>
<p>りんご</p>
<p>りんご</p>
<p>りんご</p>
<p>りんご</p>
</body>
</html>
ページ移動後
↑このページのソース
<html>
<body>
<p id="ichibanjukusita">みかん</p>
<p>みかん</p>
<p>みかん</p>
<p>みかん</p>
<p>みかん</p>
</body>
</html>
この二つのHTML文書を使い、ページ移動前と移動後で、DOMと要素がどうなるのかローカルウィンドウで観察します。
結論から言うと
- メソッドで取得する要素は、ページ移動後に再取得する必要がある
- プロパティで取得するDOMは、ページ移動後に再取得する必要なし
この結論を得るために、過剰ですが、8パターンの実験をしてみました。
要素ひとつを変数に取得し、ページ移動後、再取得せずに使用した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myElem As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myElem = ie.document.getElementsByTagName("p")(0)
ページ移動前 = myElem.innerText
ie.navigate "C:\Users\みかん.html"
ページ移動後 = myElem.innerText
End Sub
りんごの木になっている「りんご」を取りに登った、変数の myElem君。
「りんご」を取ったあとに「みかん」も欲しくなったので、みかんの木に移動したけれど、みかんの木の登りかた(メソッド)が分からなかったので
「みかん」を手に入れることはできなかった・・・・・・。
要素ひとつを変数に取得し、ページ移動後、再取得した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myElem As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myElem = ie.document.getElementsByTagName("p")(0)
ページ移動前 = myElem.innerText
ie.navigate "C:\Users\みかん.html"
Set myElem = ie.document.getElementsByTagName("p")(0)
ページ移動後 = myElem.innerText
End Sub
またまた、りんごの木になっている「りんご」を取りに登った myElem君。
「りんご」を取ったあとに「みかん」も欲しくなったので、みかんの木に移動し、みかんの木の登りかた(メソッド)を知っていたので
「みかん」も手に入れることができた。
同じ要素すべてを変数に取得し、ページ移動後、再取得せずに使用した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myCollection As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myCollection = ie.document.getElementsByTagName("p")
ページ移動前 = myCollection(0).innerText
ie.navigate "C:\Users\みかん.html"
ページ移動後 = myCollection(0).innerText
End Sub
myCollection君は大きなハンマーでりんごの木を叩き、「りんご」をすべて落としてから、「りんご」をひとつ入手した。
しばらくして「みかん」も欲しくなったので、みかんの木に移動したけれど、myCollection君はハンマーを持ってこなかったので、
「みかん」を手に入れることはできなかった・・・・・・。
同じ要素すべてを変数に取得し、ページ移動後、再取得した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myCollection As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myCollection = ie.document.getElementsByTagName("p")
ページ移動前 = myCollection(0).innerText
ie.navigate "C:\Users\みかん.html"
Set myCollection = ie.document.getElementsByTagName("p")
ページ移動後 = myCollection(0).innerText
End Sub
myCollection君は「りんご」を取ったあと、みかんの木がある場所にハンマーを持ってきたので、「みかん」をすべて落とし、目的の「みかん」を入手することに成功した。
IDで指定した要素を変数に取得し、ページ移動後、再取得せずに使用した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myId As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myId = ie.document.getElementById("ichibanjukusita")
ページ移動前 = myId.innerText
ie.navigate "C:\Users\みかん.html"
ページ移動後 = myId.innerText
End Sub
myId君は、目印のついている実を打ち落とすことができる魔法の銃を持っています。まず、「りんご」を打ち落とし、
次にみかんの木に移動しました。・・・・・・が、目印を忘れてしまったため、
「みかん」を打ち落とすことができませんでした・・・・・・。
IDで指定した要素を変数に取得し、ページ移動後、再取得した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myId As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myId = ie.document.getElementById("ichibanjukusita")
ページ移動前 = myId.innerText
ie.navigate "C:\Users\みかん.html"
Set myId = ie.document.getElementById("ichibanjukusita")
ページ移動後 = myId.innerText
End Sub
myId君は「りんご」を取ったあと、みかんの木に移動しました。今度は、目印の"ichibanjukusita"を思い出したので、
「みかん」も打ち落とすことができました。
documentプロパティでDOMを変数に取得し、ページ移動後、再取得せずに使用した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myDoc As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myDoc = ie.document
ページ移動前 = myDoc.getElementsByTagName("p")(0).innerText
ie.navigate "C:\Users\みかん.html"
ページ移動後 = myDoc.getElementsByTagName("p")(0).innerText
End Sub
myDocさんは、みんなに木の実の取り方を教えてくれる先生です。
myDocさんは、一つの窓から望遠鏡を使って、いろんな場所にある木のかたちを見ることができます。しかし、一回望遠鏡を使ってしまえば、あとは望遠鏡なしでも、いろんな場所にある木のかたちをライブで見ることができます。
これは、望遠鏡の使用で発動する myDocさんの特殊能力です。
documentプロパティでDOMを変数に取得し、ページ移動後、再取得した場合
Sub test()
Dim ie As Object
Dim sh As Object
Dim win As Object
Dim myDoc As Object
Dim ページ移動前 As String
Dim ページ移動後 As String
Set sh = CreateObject("Shell.Application")
For Each win In sh.Windows
If win.Name = "Internet Explorer" Then
Set ie = win
Exit For
End If
Next
Set myDoc = ie.document
ページ移動前 = myDoc.getElementsByTagName("p")(0).innerText
ie.navigate "C:\Users\みかん.html"
Set myDoc = ie.document
ページ移動後 = myDoc.getElementsByTagName("p")(0).innerText
End Sub
myDocさんは一回望遠鏡を使ってしまえば、あとは望遠鏡なしでもいろんな場所にある木のかたちをライブで見ることができます。だからその都度、望遠鏡を使っていろんな場所にある木を見ることができるのは当然ですね。
まとめ
8パターンの実験結果は、下記のようになりました。
方法 | りんご入手 | みかん入手 |
---|---|---|
要素1個を変数に取得し、ページ移動後、変数をそのまま利用 | OK | NG |
要素1個を変数に取得し、ページ移動後、変数に再取得して利用 | OK | OK |
要素のすべてを変数に取得し、ページ移動後、変数をそのまま利用 | OK | NG |
要素のすべてを変数に取得し、ページ移動後、変数に再取得して利用 | OK | OK |
IDから要素1個を変数に取得し、ページ移動後、変数をそのまま利用 | OK | NG |
IDから要素1個を変数に取得し、ページ移動後、変数に再取得して利用 | OK | OK |
documentプロパティでDOMを変数に取得し、ページ移動後、変数をそのまま利用 | OK | OK |
documentプロパティでDOMを変数に取得し、ページ移動後、変数に再取得して利用 | OK | OK |
冒頭で結論を先に言ってしまったので繰り返しになりますが、
ページを移動したら
- 要素は再取得する必要がある
- DOM は(変数に入っていても)再取得しなくてよい。常に最新の状態である
ということが、実験で分かりました。