WebViewコントロール(MAUI)によるHTML要素の指定

WebViewコントロール(MAUI)のHTML要素へのアクセス方法について

WebViewコントロール(MAUI)にはDOMを直接操作するメソッドはありません。
代わりの手段としてEvaluateJavaScriptAsyncメソッドを使います。

EvaluateJavaScriptAsyncメソッドは、表示しているWebページに対してJavaScriptを実行できますので、
JavaScriptでDOMを操作するコードを作成し、実行してやります。

※WebViewコントロール(MAUI)でのJavaScript実行についてはこちらを参照。

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

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

実装方法

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

JavaScript書式

document.getElementById("id").~

サンプル

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void OnJsClicked(object sender, EventArgs e)
						{
							await MyWebView.EvaluateJavaScriptAsync("document.getElementById('inputid2').value = 'テキスト2 all id';");
						}
					

参考

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

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

実装方法

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

JavaScript書式

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

※nは0~の数値

サンプル

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

参考

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

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

実装方法

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

JavaScript書式

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

サンプル

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void OnJsClicked(object sender, EventArgs e)
						{
							//指定するclass属性の0番目にアクセス
							await MyWebView.EvaluateJavaScriptAsync("document.getElementsByClassName('inputclass')[0].value = 'テキスト1 class 0';");
						}
					

参考

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

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

実装方法

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

JavaScript書式

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

サンプル

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

参考

アンカー要素にアクセス

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

実装方法

JavaScriptの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 void OnJsClicked(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 + ' ';\\");
							js.AppendLine("    str += document.links[i].innerText + ' ';\\");
							//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 MyWebView.EvaluateJavaScriptAsync(js.ToString());
						}
					

参考

form内の要素にアクセス

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

実装方法

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

JavaScript書式

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

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

サンプル

						private async void OnJsClicked(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 MyWebView.EvaluateJavaScriptAsync(js.ToString());
						}
					

参考

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

CSSセレクタを指定して一致する要素にアクセスする方法です。

実装方法

JavaScriptのquerySelectorquerySelectorAllメソッドを使うことで、CSSセレクタによる要素の取得が行なえます。

CSSセレクタは、要素を特定するための簡易なCSSの指定方法のようなものです。
querySelectorメソッドは指定されたセレクタに最初に一致した要素を返却します。見つからない場合はnullを返却します。
querySelectorAllメソッドは指定されたセレクタに一致した要素をすべて返却します。見つからない場合は空のリストを返却します。

サンプル

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						//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セレクタのデバッグ

参考

iframe内の要素にアクセス

iframe内の要素にアクセスする方法です。
MAUIでiframeにアクセス

実装方法

他の要素取得と同じ方法でiframeのオブジェクトを取得してから、
その要素に対してDOMでアクセスします。

サンプル

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void OnJsClicked(object sender, EventArgs e)
						{
							System.Text.StringBuilder js = new System.Text.StringBuilder();
							js.AppendLine("var iframe = document.getElementById('inline_frame');\\");
							js.AppendLine("iframe.contentWindow.document.getElementById('inputid2').value = 'テキスト2';\\");
							await MyWebView.EvaluateJavaScriptAsync(js.ToString());
						}
					

shadow-root内の要素にアクセス

shadow-root(open)内の要素にアクセスする方法です。
MAUIでshadow-rootにアクセス

実装方法

まず、他の要素取得と同じ方法でshadow-rootの親となる要素を取得します。
その要素に対してDOMでアクセスします。

サンプル

						//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で
						private async void OnJsClicked(object sender, EventArgs e)
						{
							System.Text.StringBuilder js = new System.Text.StringBuilder();
							js.AppendLine("var shadowroot = document.getElementById('sr');\\");
							js.AppendLine("shadowroot.shadowRoot.getElementById('inputid1').value = 'テキスト';\\");
							await MyWebView.EvaluateJavaScriptAsync(js.ToString());
						}