【问题标题】:How to search for string in html files using Javascript?如何使用 Javascript 在 html 文件中搜索字符串?
【发布时间】:2018-03-30 16:44:27
【问题描述】:

我有 5 个 html 文件,我有一个搜索表单,我想用它来搜索这些 html 文件中的文本。

<form>
   <input type ='text' />
   <input type ='submit' />
</form>

我有一个使用 xmlhttprequest 获取文件的想法

var xhr = new XMLHttpRequest();
xhr.open("GET", "file1.html", false);
xhr.send();
var guid = xhr.responseText;

var xhr = new XMLHttpRequest();
xhr.open("GET", "file2.html", false);
xhr.send();
var guid = xhr.responseText;

...

然后在这些文件中搜索文本,但我不知道如何使用 javascript 在文件中搜索。

使用 xmlhttprequest 获取文件后如何搜索文件?或者是否有另一种使用 javascript 进行搜索的方法?

【问题讨论】:

  • 正则表达式可以工作,或者 indexOf() ...但您需要等待请求完成,然后再尝试处理内容。谷歌 XMLHttpeRequest 事件以获取有关如何执行此操作的更多信息。
  • @theGleep ,如果您有示例或资源来获得我想要的东西,请告诉我

标签: javascript html dom xmlhttprequest


【解决方案1】:

首先,改变:

<input type ='text' />

收件人:

<input id= 'text' type='text' />

然后,下面的代码将创建一个由对象组成的名为“文件”的数组。每个对象的“位置”属性将包含“文本”在“文件名”中的位置,如果未找到文本,则为 -1,如果未加载文件,则为 -2。

var text = document.getElementById('text' )

loadCount = 0;
files = [];
files[ 0 ] = {};
files[ 0 ][ 'filename' ] = "file1.html";
files[ 1 ] = {};
files[ 1 ][ 'filename' ] = "file2.html";
files[ 2 ] = {};
files[ 2 ][ 'filename' ] = "file3.html";
files[ 3 ] = {};
files[ 3 ][ 'filename' ] = "file4.html";
files[ 4 ] = {};
files[ 4 ][ 'filename' ] = "file5.html";

function search( item, index ) {

  xmlhttp.onload = function () {
    var files[ index ][ 'contents' ]  = xhr.responseText;
    if ( typeof files[ index ][ 'contents' ] !== 'undefined' ) {
      files[ index ][ 'position' ] = str.indexOf( text );
    } else {
      files[ index ][ 'position' ] = -2;
    }
    loadCount = loadCount + 1;
    if ( loadCount == 5 ) {
      // do whatever you want here
    }
  }

  var xhr = new XMLHttpRequest();
  xhr.open( "GET", item[ 'filename' ], false );
  xhr.send();

}

files.forEach( search );

【讨论】:

  • 谢谢,但我可以在哪里使用包含插入到搜索输入中的文本的变量?如果我想加载包含与插入到搜索输入中的内容相匹配的文本的文件怎么办?
  • @tommy 我已经更新了答案以从文本输入字段中获取文本,并将每个文件的内容放在每个对象的“内容”属性中。你可以在那里访问它。
【解决方案2】:

我会使用DOMParser 来确保我们正在进行一些“智能”搜索。假设您正在寻找有关“视口”一词的文本;您不希望任何具有&lt;meta&gt; 标签“viewport”的 HTML 文件作为有效结果返回,对吗?

第一步是将字符串解析为 Document 实例:

const parseHTMLString = (() => {
  const parser = new DOMParser();
  return str => parser.parseFromString(str, "text/html");
})();

在此处输入一个有效的 HTML 字符串,您将得到一个与 window.document 行为类似的文档作为回报!这意味着我们可以做各种很酷的事情,比如使用querySelectorinnerText 等属性。

下一步是定义我们要搜索的内容。下面是一个加入文档标题和正文的示例:

const getSearchStringForDoc = doc => {
  return [ doc.title, doc.body.innerText ]
   .map(str => str.toLowerCase().trim())
   .join(" ");
};

将解析后的文档传递给此函数,您将得到一个纯字符串作为返回,其中仅包含内容,没有属性、标签名称和元数据。

现在,问题在于定义正确的搜索方法。可能是基于正则表达式的匹配,或者只是(速度较慢)split & includes

const stringMatchesQuery = (str, query) => {
  return query
    .toLowerCase()
    .split(/\W+/)
    .some(q => str.includes(q))
};

将这些方法链接在一起,您就得到了如下转换:

String -> Document -> String -> Boolean

如果您想在搜索内容中包含更多信息,只需使用标准化 API 更新 getSearchStringForDoc 函数即可。

一个正在运行的示例(这有点混乱,可以进行一些重构,但希望能理解重点):

const htmlString =  (
`<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>The title</title>
</head>
<body>
  Some text about an interesting thing.
</body>
</html>`);

const parseHTMLString = (() => {
  const parser = new DOMParser();
  return str => parser.parseFromString(str, "text/html");
})();

const getSearchStringForDoc = doc => {
  return [
    doc.title,
    doc.body.innerText
  ].map(str => str.trim())
   .join(" ");
};

const stringMatchesQuery = (str, query) => {
  str = str.toLowerCase();
  query = query.toLowerCase();
  
  return query
    .split(/\W+/)
    .some(q => str.includes(q))
};

const htmlStringMatchesQuery = (str, query) => {
  const htmlDoc = parseHTMLString(str);
  const htmlSearchString = getSearchStringForDoc(htmlDoc);
  
  return stringMatchesQuery(htmlSearchString, query);
};

console.log("Match 'viewport':", htmlStringMatchesQuery(htmlString, "viewport"));
console.log("Match 'Interesting':", htmlStringMatchesQuery(htmlString, "Interesting"));

【讨论】:

  • 谢谢你,但我不明白所有的代码,所以如果你不介意,我想问你一些事情
  • 会有一个文本插入到输入文本中,因此例如在单击输入提交时创建一个函数以使用javascript获取输入文本值,然后在所有5个html文件中搜索并查找是否插入的文本是否存在于其中一个 html 文件中,然后加载包含此文本的文件,例如
  • 要从文本输入中获取搜索查询,请将侦听器附加到 change 事件并使用 element.value。获得匹配的 HTML sn-p 后,您可以使用 this answer 加载它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-15
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多