Day06 - Fetchfilter正则表达式实现快速古诗匹配

Posted 链乎社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day06 - Fetchfilter正则表达式实现快速古诗匹配相关的知识,希望对你有一定的参考价值。


效果图

在输入框中搜索字或者某个词快速匹配含有这个字或者是词的诗句。

Day06 - Fetch、filter、正则表达式实现快速古诗匹配

涉及特性

  • flex布局

  • nth-child奇偶匹配

  • linear-gradient颜色渐变

  • transform

  • Fetch

  • Array

    • filter()

    • map()

    • push()

    • join()

    • ...

  • javascript RegExp 对象

    • 字面量语法

    • 创建 RegExp 对象的语法

    • 修饰符ig

    • match()

    • replace()

实现步骤

  • UI布局

  • 通过Fetch下载数据

  • 数据处理并保存

  • 事件监听

  • 数据匹配操作

  • 新数据替换展示

布局篇

  <form class="search-form">
    <input type="text" class="search" placeholder="诗人名字,关键字">
    <ul class="suggestions">
      <li>输入词句,找一首诗</li>
      <li>输入词句,找一首诗</li>
      <li>输入词句,找一首诗</li>
      <li>输入词句,找一首诗</li>
      <li>输入词句,找一首诗</li>
    </ul>
  </form>
  • CSS代码

html {  
    box-sizing: border-box;  
    margin: 0px;  
    background-color: rgb(145, 182, 195);  
    font-family: 'Kaiti', 'SimHei', 'Hiragino Sans GB ', 'helvetica neue';  
    font-size: 20px;  
    font-weight: 200;
}
*, *:before, *:after {  
    box-sizing: inherit;
}
body {  
    display: flex;  
    justify-content: center;
}
.search-form {  
    max-width: 700px;  
    display: flex;  
    flex-direction: column;  
    justify-content: center;  
    align-items: center;
}
input.search {  
    padding: 20px;  
    font-family: 'Kaiti', 'helvetica neue';  
    margin: 0;  border: 10px solid #f7f7f7;  
    font-size: 40px;  
    text-align: center;  
    width: 120%;  
    outline: 0;  
    border-radius: 5px;  
    position: relative;  
    top: 10px;  left: 10px;  
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
}
.suggestions {  
    margin: 0;  
    padding: 0;  
    position: relative;  
    top: 7px;  width: 100%;
}
.suggestions li {  
    background: white;  
    list-style: none;  
    border-bottom: 1px solid #D8D8D8;  
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);  
    margin: 0;  
    padding: 20px;  
    display: flex;  
    flex-direction: column;  
    /*align-items: flex-start;*/
}
span.title {  
    margin-right: 20px;  
    text-align: right;  
    color: #7c8e94;  
    margin-top: 5px;
}

span.hl {  
    color: green;
}
/*偶数匹配*/
.suggestions li:nth-child(even) {  
    transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);  
    background: linear-gradient(to bottom, #ffffff 0%, #efefef 100%);
}
/*奇数匹配*/
.suggestions li:nth-child(odd) {  
    transform: perspective(100px) rotateX(-3deg) translateY(3px);  
    background: linear-gradient(to top, #ffffff 0%, #efefef 100%);
}
  • CSS布局相关参考文档

    • CSS参考手册

    • CSS选择器笔记

    • flex布局完全入门教程

    • 使用HTML5里的classList操作CSS类

    • position

通过Fetch下载数据解析并且保存

const endpoint = 'https://gist.githubusercontent.com/liyuechun/f00bb31fb8f46ee0a283a4d182f691b4/raw/3ea4b427917048cdc596b38b67b5ed664605b76d/TangPoetry.json';
const poetrys = [];
fetch(endpoint)
 .then(blob => {   return blob.json();
 })
 .then(data => {
   poetrys.push(...data);
 });

具体数据请求过程见下图:

Day06 - Fetch、filter、正则表达式实现快速古诗匹配

``

Fetch详细使用文档

blob.json()是将数据转换为json数据,data为then函数中转换完的数据,在这个案例中,data是一个数组。

poetrys.push(...data)这句代码中的push是往数组里面新增对象,而...data代表的是将这个data数组中的数据一一的存储到poetrys数组中。

事件监听

const search = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');

search.addEventListener('change', displayMatches);
search.addEventListener('keyup', displayMatches);

获取searchsuggestions'节点分别对changekeyup事件进行监听,当输入框中的内容发生变化或者键盘弹起时触发displayMatches函数更新数据。

数据匹配操作

  • RegExp使用基础

RegExp参考文档

  • 项目源码分析

function findMatches(wordToMatch, poetrys) { 
    return poetrys.filter(poet => {   // 正则找出匹配的诗句
   const regex = new RegExp(wordToMatch, 'gi');   
   const author = poet.detail_author.join('');   
   //           console.log(author);
   return poet.detail_text.match(regex) || poet.title.match(regex) || author.match(regex);
 });
}

function displayMatches() { 

    const matches = findMatches(this.value, poetrys); 
    const regex = new RegExp(this.value, 'gi'); 
    const html = matches.map(poet => {   // 替换高亮的标签
   const text = poet.detail_text.replace(regex, `<span class="hl">${ this.value }</span>`);   
   const title = poet.title.replace(regex, `<span class="hl">${ this.value }</span>`);   
   const detail_author = poet.detail_author[0].replace(regex, `<span class="hl">${ this.value }</span>`);   // 构造 HTML 值
   return `
 <li>
   <span class="poet">${ text }</span>
   <span class="title">${ title } - ${ detail_author }</span>
 </li>
`;
 }).join(''); //     console.log(html);
 suggestions.innerHTML = html;
}
  • poetrys.filter会返回带搜索关键字的新数组。

  • const regex = new RegExp(this.value, 'gi'); 代表匹配规则。

  • g:执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。

  • i:执行对大小写不敏感的匹配。

  • 上面的这种写法等价于:"/this.value/gi"。

  • matches.map会返回一个按照新的规则处理完以后的新的数组。

  • title.replace(regex, "新字符串");表示将title字符串中满足 regex 规则的字符串替换成新字符串

源码下载

Github Source Code

社群品牌:从零到壹全栈部落

定位:寻找共好,共同学习,持续输出全栈技术社群

业界荣誉:IT界的逻辑思维

文化:输出是最好的学习方式

社群发起人:春哥(从零到壹创始人,交流微信:liyc1215)

技术交流社区:全栈部落BBS

全栈部落完整系列教程:全栈部落完整电子书学习笔记

关注全栈部落官方公众号,每晚十点接收系列原创技术推送
Day06 - Fetch、filter、正则表达式实现快速古诗匹配


扫描二维码

申请加入全栈部落


以上是关于Day06 - Fetchfilter正则表达式实现快速古诗匹配的主要内容,如果未能解决你的问题,请参考以下文章

2018-06-27-Python全栈开发day22-part2-xml模块和re模块-正则表达式介绍

猫鼬查询正则表达式以忽略中间字符

如何使用 jQuery 将正则表达式应用于输入?

JavaScript学习(六十九)—正则表达式实训题

5-python自动化-day05

Python自动化开发课堂笔记Day06 - Python基础(模块)