本記事は 2026/02/01 ~ 2026/03/01 の間毎日 AI アプリケーション開発(AI を搭載したアプリ開発 or AI を使用した開発)をテーマに 30 days AI challenge を行う 11 日目のブログポストです。
今日はアプリを作ったというより、ブラウザ内にもう 1 つブラウザを作成してみました(ややこしいのでアプリと呼びます)。
アプリ自体に AI 機能はありませんが、GitHub Copilot を使って開発したので AI challenge に含めています。
アプリの概要
アプリの外観はこちら。

ブラウザで Blazor ウェブアプリにアクセスし、その中にさらにもう一つのブラウザがあります。
URL を直接入力することでサイトへアクセスすることもでき、検索エンジンから検索も可能です。
ただし、一部の JavaScript の動作や画像読み込みがうまくいかずちょくちょくエラーや warning をはいています。このあたりは後で修正予定です。
このアプリの特徴として “消しゴム機能” があります。消しゴムボタンをクリックすると、消しゴムモードが有効となり、その状態でサイト内をクリックすると、選択したオブジェクトを削除することができます(HTML 要素を削除します)。※某スマホのブラウザにここ数年で搭載された機能に近いです。
例えば以下のように、miyacle のブログサイトの説明欄や画像を削除することもできます。このなんちゃってブラウザアプリを作りたかったのはこのオブジェクト削除機能を作りたかったからです。

技術要素
冒頭にも記載しましたが、今回のアプリには AI 機能はありません。
そのためブラウザ機能に関する説明にはなりますが、消しゴム機能は以下のように実装しています(実装の一部)。
body と doumentElement 自体は削除されないようにし、他は選択したオブジェクトを element.remove(); で削除します。
iframeDoc.addEventListener('click', (e) => {
// 1.消しゴムモードかチェック
const eraserMode = localStorage.getItem('eraserMode') === 'true';
// 2.消しゴムモードONなら、要素を削除
if (eraserMode && e.target &&
e.target !== iframeDoc.body &&
e.target !== iframeDoc.documentElement)
{
e.preventDefault(); // デフォルト動作をキャンセル
e.stopPropagation(); // 親要素への連携を停止
const element = e.target;
// フェードアウトアニメーション
element.style.opacity = '0.5';
element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out';
element.style.transform = 'scale(0.95)';
// 0.3秒後に要素を削除
setTimeout(() => {
element.remove();
}, 300);
return; // ここで処理終了
}
~一部省略~
}, true);
お気づきとは思いますが、前述の Element 要素取得や DOM 操作は JavaScript での実装となっています。
Blazor から JS ファイルを呼び出して、Blazor – JavaScript とお互い呼び出しあって処理を行っています。
browserModule = await JS.InvokeAsync<IJSObjectReference>(
"import",
"./js/browser.js"
);
おわりに
実は、今日のブラウザアプリはなかなバグが多いアプリになっています笑
なかなか想定通りの挙動をしてくれず、AI 生成のコードを見ても難解なのでデバッグに非常に苦労しています。
また、ブラウザ側の挙動にもなるので、ログの取り方も工夫する必要がありそのあたりも非常にデバッグを難しくしていました。
AI は build error や明示的なエラーの解消に役立ちますが、エラーのない状態での想定外の動作にはトライアル & エラーを繰り返すしかなく、むしろ AI の推論より人間の原因推測のほうが優れているように感じました。
今日は以上となります。明日もよろしくお願いします!

コメント