2025年4月16日水曜日

同一フォルダー内のすべてのファイルを検索対象にするには

 同一フォルダー内のすべてのファイルを検索対象にするというご要望ですが、クライアント側の JavaScript(ブラウザで動作する JavaScript)のみでは、セキュリティ上の理由からローカルファイルシステム内のすべてのファイルにアクセスすることはできません。

ブラウザは、ユーザーの許可なしにローカルファイルを読み取ることはできないように設計されています。そのため、JavaScriptだけで同一フォルダー内の .html ファイルや .txt ファイルなどを自動的に読み込んで検索することはできません。

もし、実現したいことが以下のようなケースであれば、いくつかの方法が考えられますが、JavaScript単独では難しい場合があります。

  • 複数の HTML ファイルをまとめて検索したい:

    • 方法 1 (簡易的): 各 HTML ファイルに先ほどの検索コードを埋め込み、それぞれのページで検索を実行する形になります。ページを移動するたびに検索を行う必要があります。
    • 方法 2 (より高度): サイトジェネレーターのようなツールを使って、複数のファイルから静的なウェブサイトを生成する際に、検索用のインデックスを作成する仕組みを導入する必要があります。これには、Node.jsなどのサーバーサイド技術や、Lunr.jsのようなクライアントサイドの全文検索ライブラリの利用が考えられます。
  • HTML ファイル以外のファイル(テキストファイルなど)も検索したい:

    • これはさらに複雑になります。通常は、サーバーサイドのプログラム(例えば Python、PHP、Node.js など)を使ってファイルを読み込み、検索処理を行う必要があります。

今回は、現状のコードをベースに、検索結果のテキスト中で見つかったキーワードをマーク(ハイライト表示)する方法に焦点を当てて解説します。

JavaScript コードの修正:

以下の JavaScript コードでは、検索結果のリスト表示において、見つかったキーワードを <span class="highlight"> タグで囲み、CSS でハイライト表示するように変更します。

JavaScript
function searchContent() {
  const searchTerm = document.getElementById('search-input').value.toLowerCase();
  const contentDiv = document.getElementById('content');
  const resultsList = document.getElementById('results-list');
  resultsList.innerHTML = ''; // 検索結果をクリア

  const elementsToSearch = contentDiv.querySelectorAll('h2, h3, p');
  let resultsFound = false;

  elementsToSearch.forEach(element => {
    const textContent = element.textContent;
    const lowerCaseTextContent = textContent.toLowerCase();

    if (lowerCaseTextContent.includes(searchTerm)) {
      resultsFound = true;
      const listItem = document.createElement('li');

      // マッチしたキーワードをハイライト表示
      const highlightedText = textContent.replace(
        new RegExp(searchTerm, 'gi'),
        '<span class="highlight">$&</span>'
      );

      listItem.innerHTML = element.tagName + ": " + highlightedText;
      resultsList.appendChild(listItem);
    }
  });

  if (!resultsFound) {
    const listItem = document.createElement('li');
    listItem.textContent = '該当するコンテンツは見つかりませんでした。';
    resultsList.appendChild(listItem);
  }
}

変更点:

  • textContent を直接使用するように戻しました(ハイライトのために元のテキストを保持)。
  • textContent.replace() メソッドと正規表現 (new RegExp(searchTerm, 'gi')) を使用して、検索キーワード(大文字・小文字を区別せず、複数回出現する場合もすべて)を <span class="highlight">$&</span> で囲んでいます。$& は、マッチした文字列全体を表します。
  • listItem.textContent ではなく、listItem.innerHTML にハイライトされたテキストを設定しています。

HTML (変更なし):

HTML コードは前回と同じものを使用できます。

HTML
<!DOCTYPE html>
<html>
<head>
<title>キーワード検索</title>
<style>
  #search-results {
    margin-top: 10px;
    border: 1px solid #ccc;
    padding: 10px;
  }
  #search-results ul {
    list-style-type: none;
    padding: 0;
  }
  #search-results li {
    margin-bottom: 5px;
  }
  .highlight {
    background-color: yellow;
    font-weight: bold;
  }
</style>
</head>
<body>

  <h1>ウェブサイトのコンテンツ</h1>

  <div id="search-container">
    <input type="text" id="search-input" placeholder="キーワードを入力">
    <button onclick="searchContent()">検索</button>
  </div>

  <div id="content">
    <h2>セクション 1</h2>
    <p>これは最初のセクションの内容です。キーワード検索のテストを行います。</p>
    <h3>サブセクション 1.1</h3>
    <p>このサブセクションにもキーワード検索という言葉が含まれています。</p>
    <h2>セクション 2</h2>
    <p>二つ目のセクションです。ここでは別のキーワード、例えばホームページについて説明します。</p>
    <h3>サブセクション 2.1</h3>
    <p>ホームページ作成は楽しいですね。</p>
  </div>

  <div id="search-results">
    <h3>検索結果</h3>
    <ul id="results-list"></ul>
  </div>

  <script>
    // 上記の修正された JavaScript コードをここに貼り付けてください
  </script>

</body>
</html>

動きの確認:

この修正を加えた HTML ファイルをブラウザで開き、キーワードを入力して検索すると、検索結果のリストに表示されたテキストの中で、入力したキーワードが黄色くハイライト表示されるようになります。

同一フォルダー内のすべてのファイルを検索することについて(再掲):

重ねてになりますが、ブラウザの JavaScript だけでローカルファイルシステムにアクセスして複数のファイルを検索することはセキュリティ上の制約があります。もし、複数の HTML ファイルや他の種類のファイルを対象とした本格的なサイト内検索機能を実装したい場合は、以下のような方法を検討する必要があります。

  • サーバーサイドでの検索: サーバー側でファイルの読み込みと検索処理を行い、検索結果をクライアント(ブラウザ)に送信する仕組みを構築します。
  • 静的サイトジェネレーターと検索インデックス: 静的サイトジェネレーターを利用してウェブサイトを構築する際に、検索用のインデックスファイルを生成し、クライアント側の JavaScript ライブラリ(例: Lunr.js, Elasticlunr.js)を使って検索を行う。

ご希望の実現方法に応じて、これらの選択肢をご検討ください。もし、特定の技術や環境での実現方法についてさらに質問があれば、お気軽にお尋ねください。

0 件のコメント:

コメントを投稿