WebView2コントロールによるHTML要素の指定

WebView2コントロールで表示しているWebページのテキストボックスやボタンなどのHTML要素に対して、 プログラムで値を設定したりクリックしたりすることができます。
これら操作を行うためには、まずは操作対象のHTML要素を探し出す必要があります。
htmlのコードに設定されているid属性やname属性等の情報を使って要素を特定する方法について説明します。

ページ内のすべての要素にアクセス

name属性、id属性、インデックス番号を指定してページ内(document内)の全ての要素にアクセスする方法です。

※HTML5では「Document.all」は非推奨となっていますので、後述する「getElementById」「getElementsByName」などを使いましょう。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.allプロパティを使用します。
allプロパティにname属性、id属性、インデックス番号を指定して要素を特定します。
name属性を指定した場合は複数の要素が取得されるため、さらに要素を特定するためにインデックス番号も指定する必要があります。

allプロパティは「HTMLAllCollection」を取得します。
allプロパティにname属性を指定すると、1件見つかった場合は「Element」が取得され、 複数見つかった場合は「HTMLCollection」が取得され、見つからない場合はnullが返却されます。 allプロパティにid属性やインデックスを指定すると「Element」が取得され、見つからない場合はnullが返却されます。

サンプル

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles btnAllProperty.Click
							Await WebView2.ExecuteScriptAsync("document.all('inputid2').value = 'テキスト2 all id';")
							Await WebView2.ExecuteScriptAsync("document.all.item('inputid3').value = 'テキスト3 all item id';")
						End Sub
					
						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void btnAllProperty_Click(object sender, EventArgs e)
						{
							await webView2.ExecuteScriptAsync("document.all('inputid2').value = 'テキスト2 all id';");
							await webView2.ExecuteScriptAsync("document.all.item('inputid3').value = 'テキスト3 all item id';");
						}
					

参考

id属性を指定して要素にアクセス

id属性を指定して一致する要素にアクセスする方法です。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.getElementByIdメソッドを使用します。
getElementByIdメソッドの引数にid属性を指定して要素を特定します。
特定した要素は「Element」オブジェクトまたはnull(一致する要素がない場合)が取得されます。

JavaScript書式

document.getElementById("id").~

サンプル

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で

						Private Async Sub btnGetID_Click(sender As Object, e As EventArgs) Handles btnGetID.Click
							Await WebView2.ExecuteScriptAsync("document.getElementById('inputid2').value = 'テキスト2 all id';")
						End Sub
					
						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
		
						private async void btnGetId_Click(object sender, EventArgs e)
						{
							await webView2.ExecuteScriptAsync("document.getElementById('inputid2').value = 'テキスト2 all id';");
						}
					

参考

name属性を指定して要素にアクセス

name属性を指定して一致する複数の要素にアクセスする方法です。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.getElementsByNameメソッドを使用します。
getElementsByNameメソッドの引数にname属性を指定して要素を特定します。
name属性は同名が複数存在しますので、結果も複数取得されます。
特定した要素は「HTMLCollection/NodeList」またはnull(一致する要素がない場合)が取得されます。

JavaScript書式

document.getElementsByName("name属性")[n].~

※nは0~の数値

サンプル

						Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

							'Yahooの検索欄に文字を設定する
							Await WebView2.ExecuteScriptAsync($"document.getElementsByName('p')[0].value = 'プログラムでネットサーフィン!';")
									
						End Sub

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						Private Async Sub btnGetName_Click(sender As Object, e As EventArgs) Handles btnGetName.Click

							Await WebView2.ExecuteScriptAsync("document.getElementsByName('inputname')[0].value = 'テキスト1 all name 0';")

						End Sub
					
						async private void button1_Click(object sender, EventArgs e)
						{
							//Yahooの検索欄に文字を設定する
							await webView2.ExecuteScriptAsync("document.getElementsByName('p')[0].value = 'プログラムでネットサーフィン!';");
						}

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void btnGetName_Click(object sender, EventArgs e)
						{
							await webView2.ExecuteScriptAsync("document.getElementsByName('inputname')[1].value = 'テキスト2 all name 1';");
						}
					

参考

class属性を指定して要素にアクセス

class属性を指定して一致する複数の要素にアクセスする方法です。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.getElementsByClassNameメソッドを使用します。
getElementsByClassNameメソッドの引数にclass属性を指定して要素を特定します。
class属性は同名が複数存在しますので、結果も複数取得されます。
特定した要素は「HTMLCollection」またはnull(一致する要素がない場合)が取得されます。

JavaScript書式

document.getElementsByClassName('inputclass')[0].~

サンプル

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で

						Private Async Sub btnGetClass_Click(sender As Object, e As EventArgs) Handles btnGetClass.Click

							'指定するclass属性の0番目にアクセス
							Await WebView2.ExecuteScriptAsync("document.getElementsByClassName('inputclass')[0].value = 'テキスト1 class 0';")
						
						End Sub
					
						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で

						private async void btnClass_Click(object sender, EventArgs e)
						{
							//指定するclass属性の0番目にアクセス
							await webView2.ExecuteScriptAsync("document.getElementsByClassName('inputclass')[0].value = 'テキスト1 class 0';" );
						}
					

参考

タグ名を指定して要素にアクセス

タグ名を指定して一致する複数の要素にアクセスする方法です。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.getElementsByTagNameメソッドを使用します。
getElementsByTagNameメソッドの引数にタグ名を指定して一致する要素を全て抽出します。
タグは同名が複数存在しますので、結果も複数取得されます。
特定した要素は「HTMLCollection」またはnull(一致する要素がない場合)が取得されます。

JavaScript書式

document.getElementsByTagName('tag')[0].~

サンプル

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で

						Private Async Sub btnGetTag_Click(sender As Object, e As EventArgs) Handles btnGetTag.Click

							'inputタグの0番目にアクセス
							Await WebView2.ExecuteScriptAsync("document.getElementsByTagName('input')[0].value = 'テキスト1 tag 0';")

						End Sub
					
						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void btnTag_Click(object sender, EventArgs e)
						{
							//inputタグの0番目にアクセス
							await webView2.ExecuteScriptAsync("document.getElementsByTagName('input')[0].value = 'テキスト1 tag 0';");
						}
					

参考

アンカー要素にアクセス

href属性を持つすべてのarea要素とアンカー要素にアクセスする方法です。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.linksプロパティを使用します。
document.linksプロパティで全てのアンカー要素が取得できます。インデックス番号を指定すると該当するアンカー要素を取得します。
特定した要素は「HTMLCollection」またはnull(一致する要素がない場合)が取得されます。

JavaScript書式

//アンカー要素を全て取得する
document.links

//nに0~の数値を指定することで、該当するアンカー要素を取得する
document.links(n)

//アンカー要素の数を取得する。
document.links.length

サンプル

						'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						Private Async Sub btnAnchr_Click(sender As Object, e As EventArgs) Handles btnAnchr.Click

							Dim js As New System.Text.StringBuilder
							js.AppendLine("var str = '';")
							js.AppendLine("for (let i = 0; i < document.links.length; i++)")
							js.AppendLine("{")
							js.AppendLine("    str += document.links[i].href + '\n';")
							js.AppendLine("    str += document.links[i].innerText + '\n';")
							js.AppendLine("    if(document.links[i].innerText == 'リンク1') document.links[i].click();")
							js.AppendLine("}")
							js.AppendLine("alert(str);")
			
							Await WebView2.ExecuteScriptAsync(js.ToString())

						End Sub
					
						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void btnAnchr_Click(object sender, EventArgs e)
						{
							System.Text.StringBuilder js = new System.Text.StringBuilder();
							js.AppendLine("var str = '';");
							js.AppendLine("for (let i = 0; i < document.links.length; i++)");
							js.AppendLine("{");
							js.AppendLine("    str += document.links[i].href + '\\n';");
							js.AppendLine("    str += document.links[i].innerText + '\\n';");
							js.AppendLine("    if(document.links[i].innerText == 'リンク1') document.links[i].click();");
							js.AppendLine("}");
							js.AppendLine("alert(str);");

							await webView2.ExecuteScriptAsync(js.ToString());
						}
					

参考

form内の要素にアクセス

form要素内の全ての要素にアクセスする方法です。
form要素の指定は、name属性、id属性、インデックス番号が使用できます。
submit/resetの実行が行えます。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

documentのformsプロパティを使用します。
formsプロパティにname属性、id属性、インデックス番号を指定してform要素を特定します。
特定したform内の全ての要素は「HtmlCollection」で取得できます。

JavaScript書式

//ページの先頭からn番目のform要素にアクセスします。(nは0~の数値)
document.forms[index]

//form要素に定義されているid/name属性を指定します。
document.forms["name属性またはid属性"]

サンプル

						Private Async Sub btnForm_Click(sender As Object, e As EventArgs) Handles btnForm.Click

							Dim js As New System.Text.StringBuilder
							js.AppendLine("document.forms['testform1'].reset();")
							js.AppendLine("document.forms['testform1'][0].value = 100;")
							js.AppendLine("document.forms['testform1']['checkname'].checked = true;")
							js.AppendLine("document.forms['testform1'].submit();")

							Await WebView2.ExecuteScriptAsync(js.ToString())

						End Sub
					
						private async void btnForm_Click(object sender, EventArgs e)
						{
							System.Text.StringBuilder js = new System.Text.StringBuilder();
							js.AppendLine("document.forms['testform1'].reset();");
							js.AppendLine("document.forms['testform1'][0].value = 100;");
							js.AppendLine("document.forms['testform1']['checkname'].checked = true;");
							js.AppendLine("document.forms['testform1'].submit();");
		
							await webView2.ExecuteScriptAsync(js.ToString());
						}
					

参考

CSSセレクタによる要素へのアクセス

WebView2での要素の操作はJavaScriptを使用しますので、querySelector/querySelectorAllが使えます。
CSSセレクタを指定することでマッチした要素が取得できます。

実装方法

WebView2のExecuteScriptAsyncメソッドに以下のコードを渡して実行します。
※WebView2でのJavaScript実行についてはこちらを参照。

サンプル

						//id指定
						document.querySelector('#inputid2').value = "bbbb";
	
						//class指定
						document.querySelector('.inputclass').value = "aaaa";          //最初に見つかった要素
	
						//class指定
						document.querySelectorAll('.inputclass')[4].click();           //見つかった要素の番号を指定
	
						//type指定
						document.querySelectorAll('input[type="text"]')[2].value = "cccc";
					

JavaScriptのコードが期待通りマッチするか確認するには、ブラウザの開発者ツールを使うのが簡単です。
例えばChromeのデベロッパーツールだと、ConsoleでJavaScriptのコードを入力して実行できます。
下記はセレクターのJavaScriptを実行して、期待通りに結果が得られていることが確認できます。

CSSセレクタのデバッグ

参考

座標から要素にアクセス

ブラウザの左上を基準として、指定した座標にあるHTML要素を取得します。
マウスカーソル上にあるHTML要素を取得したい場合などに使えます。

実装方法

WebView2コントロールのDOM操作はJavaScriptを使用します。

document.elementFromPointメソッドを使用します。
JavaScript書式

//xとyで指定した座標に位置する要素のオブジェクトが取得されます。
element = document.elementFromPoint(x,y);

サンプル

マウスクリックした座標にある要素のタグ名を取得して、フォーム上のラベルに表示します。
							Private Async Sub btnPoint_Click(sender As Object, e As EventArgs) Handles btnPoint.Click

								Dim js As New System.Text.StringBuilder
								js.AppendLine("var str = '';")
								js.AppendLine("document.addEventListener('click', (event) => {")
								js.AppendLine("const element = document.elementFromPoint(event.x, event.y);")
								js.AppendLine("str = element.tagName;")
								js.AppendLine("window.chrome.webview.postMessage(str);")
								js.AppendLine("});")
				
								Await WebView2.ExecuteScriptAsync(js.ToString())

							End Sub
							
							Private Sub MessageReceived(sender As Object, args As Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs) Handles WebView2.WebMessageReceived

								Label1.Text = args.TryGetWebMessageAsString()

							End Sub

							'JavaScriptからの値の取得方法についてはhttps://web.biz-prog.net/readme/webview_new3.htmlを参照
						
							private async void btnPoint_Click(object sender, EventArgs e)
							{
								System.Text.StringBuilder js = new System.Text.StringBuilder();
								js.AppendLine("var str = '';");
								js.AppendLine("document.addEventListener('click', (event) => {");
								js.AppendLine("const element = document.elementFromPoint(event.x, event.y);");
								js.AppendLine("str = element.tagName;");
								js.AppendLine("window.chrome.webview.postMessage(str);");
								js.AppendLine("});");
			
								await webView2.ExecuteScriptAsync(js.ToString());
							}
			
							private void MessageReceived(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs args)
							{
								label1.Text = args.TryGetWebMessageAsString();
							}

							//JavaScriptからの値の取得方法についてはhttps://web.biz-prog.net/readme/webview_new3.htmlを参照
						

参考