JS30 Day 6 - Type Ahead学习笔记

这次的章节,对于正规表达式不熟悉的我,是个非常难理解的,花了大概半天才理解清楚,程式码全部的意思,也希望如果有地方写得不好,请见谅,或是大大能够补充,谢谢!

这次的功能是很常见的搜寻功能,给予关键字,并会在搜寻栏下面呈现符合条件的资料。

fetch vs XMLHttpRequest

首先我们要获取资料,排除axios之外,获取资料又有分为两种方式

一种为fetch,一种为XTMLHttp,两者最大差异在于一个用callback,一个用promise
fetch虽操作较XML简单,但目前不支持进度条,超时,错误不会被拒绝。
XMLHttpRequest虽较複杂,但支持许多功能

XMLHttpRequest写法:

    function requestHandler() {      if (this.readyState !== 4) return;      if (this.status === 200) {        console.log(JSON.parse(this.response));      } else {        console.log('HTTP error');      }    }    let req = new XMLHttpRequest();    req.addEventListener('load', requestHandler);    // endpoint为要获取的资料    req.open('GET', endpoint);    req.send();    

fetch写法:

    // endpoint为要获取的资料    fetch(endpoint)      .then(item => item.json())      .then(data => console.log(data))      .catch(error => console.log(error));

fetch获取资料又有两种方式:一是直接赋值,二是解构后放进去。

let为变数宣告,除非我们所设的值是可变的用let。
const为常数宣告,在设置常数,阵列,物件,函数等类型都用const。

直接赋值

    // 直接设置空值,赋值并获取资料    // 由于cosnt一定要有值,所以不可用const宣告        let cities = null;    fetch(endpoint)      // 将资料解析(json())      .then(item => item.json())      .then(data => cities = data)      // 已成功获取资料      .then(cities => console.log(cities));

解构赋值

    // 一种设置空阵列,并利用解构一个个放进去    const citiess = [];    fetch(endpoint)      .then(item => item.json())      .then(data => citiess.push(...data));    

获取完资料后,我们要获取输入的关键字,也就是获取我们的input并增加监听事件,当关键字改变时触发,input、或keyup事件也可不用change事件,因为在< input >,< select >,< textarea >内的值改变时且不是 focus 状态时触发,也就是要当鼠标不在栏位,才会触发,故不适合。

    document.querySelector('.search').addEventListener('input', inputHandler);

而在触发后,呼叫一个函数,用来处理资料,如过滤资料、关键字的反黄,人口数的格式等。
首先,将我们的关键字以及全部资料传入至一个专门处理资料,但不影响原资料的Purefunction。

      // 将我们所输入的值(第一个参数),及全部的资料(第二个参数),传入findMatches并进行过滤      const matchArray = findMatches(this.value, cities);

RegExp

正则表达式就是用于查找符合某些複杂规则的字符串的工具,在 JavaScript 中,正规表达式也是物件。
常见的写法有两种:

一种为: 用RegExp常数,包含两个 / 字元之间的模式

const regex = /bc/gi;

一种为: 呼叫RegExp物件的建构子函数

const regex = new RegExp('los', 'gi');

正规表达之特殊字元:

正规表达模式由数个简易字元组成,例如 /abc/,或是由简易字元及特殊符号组合而成,每种组合都代表不同意思

\B:放在前面,代表前面要有东西(英文、数字、_),放在后面反之。
\b :放在前面,代表前面要没有东西,后面反之。
(?=xxx):要符合xxx。
\d:d是数字,这边是指所有数字0-9。
{}:代表字元出现次数。
+:代表+前面的字元可出现1次或多次。
(?!=xxx) : 不能符合xxx。
g : 会匹配全部

extra common

^ : 要符合在首位,ex:/^B/,Beach符合,DoBule不符合
$ : 要符合在末位,ex:/d$/,bad符合,dark不符合
. : 只要没有换行符号都符合,ex:/.a/,w a h符合,abc不符合
i : 不分大小写匹配
米字号 : 放在字后面,代表有0个对应字或多个字,ex:/ab*c/,abbbc符合,acb不符合

本实作程式码:
由后往前比较,g为匹配全部的资料,而最后一个不能为数字,且前面必须为三个数字,且可以为一组以上,而最前面要有东西结论就是最前面要有东西,且要符合每三个数字为一组,至少一组(三个数字)以上,且最后面不为数字才符合

function populationHandler(num) { return num.replace(/\B(?=(\d{3})+(?!\d))/g, ',');};

match():此方法会回传一含比对成功字串为元素的阵列,若无符合字元则回传null。

他会利用正规表达式来比对搜寻字串

string.match(regexp)

参数为regexp(正规表达式物件),如果不是,会被隐式的使用new RegExp(obj)转化成正规表达式物件。

purefunction

而下面这段代码,在const regex部分,创建一个正规表达式,第一个参数为我们所输入的关键字,
第二个参数g为比对全部资料,i为不分大小写,而在最后return部分,就是在比对资料,符合的话就返回。

    // purefunction,也就是不会改变这个function以外的东西(如word,cities),    // 经过这个function,word,cities不变,只是拿进来使用,处理完后,最后回传一个阵列。    function findMatches(word, cities) {      return cities.filter(place => {        // 利用正规表达式,去筛选符合条件的资料        const regex = new RegExp(word, 'gi');        // 只要其中一项(资料的城市或地区)符合,就回传以阵列型式且符合的资料        return place.city.match(regex) || place.state.match(regex)      });    }

replace :此方法会寻找符合的字元,并将他们以新的字元去做替换。

注意replace如果第一个参数为正则,可以把全部都替换,如果单纯用replace,换完第一个就会停止

const a = '88cdefg88';const regex = new RegExp('88', 'gi');参数为正则,全部替换a.replace(regex,gg); // ggcdefgg参数为常数,替换一个就停止a.replace('88',gg); // ggcdef88

toLocaleString:将数值型别的资料,更改为不同的显示方式,预设为英文语系,故每三个数字一个逗号

此外,除了使用正规表达式来设置数字格式之外,我们还可利用toLocaleString来达到效果。

function populationHandler(num) {      // 因为在json中资料(population)是以字串型式,所以为了使用toLocaleString,      // 要将资料转为数值,故利用*1强制转型即可       return (num * 1).toLocaleString();};

join():join将字串以括号内的元素合成一个字串

不加上参数的话预设以,隔开,此处用空不加上join的话,每个Li中间都会有逗号隔开(因为阵列关係)。
如下图
http://img2.58codes.com/2024/201261828iNu6dn4KY.png

    function inputHandler() {      // 将我们所输入的值(第一个参数),及全部的资料(第二个参数),传入findMatches并进行过滤      const matchArray = findMatches(this.value, cities);      console.log(matchArray); // 会获取条件过滤后的资料      // 获取过滤完的资料后,以列表呈现在搜寻框下      const html = matchArray.map(place => {        const regex = new RegExp(this.value, 'gi');        // 将地区及城市的关键字,以有颜色的字体去取代        const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);        const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);        // 最后回传符合条件的城市,地区,及处理好的对应人口        return `      <li>        <span class="name">${cityName}, ${stateName}</span>        <span class="population">${numberWithCommas(place.population)}</span>      </li>    `;        // join将字串以括号内的元素合成一个字串,预设为,,此处用空        // 不加join的话每个Li中间都会有逗号隔开(因为阵列关係)      }).join('');      console.log(html);      document.querySelector('.suggestions').innerHTML = html;    }

而我们再拿到过滤完的资料后,需要将资料呈现出来,因为回传的资料是以阵列型式
,故利用map对每个资料做处理,利用replace方法去改变每笔符合资料,关键字的颜色
,并回传一个以正规表达式处理好的人口数,然后将整个阵列,用join方法切割并合併
成一个字串,最后放进ul里面即可

完整结果如下图

http://img2.58codes.com/2024/20126182KLlP4mkdSW.png


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章