前言
先看成品 (From JS30 06-Type Ahead )
正文
Fetch
整个数据是从公共 api 请求到的,因此用了简单的 Fetch 来获取数据
js
const endpoint = 'https://example.com';
fetch(endpoint)
.then(res => res.json())
.then(data => console.log(data));
Response
第一个 .then 拿到的是 Response 对象,即服务器的直接返回结果
- Fetch 只有在网络错误或者无法连接 时才会报错,其他情况都认为请求成功 ,因此状态码为 4xx,5xx 时,Promsie 也不会走 rejected,故在封装 Fetch 时需手动使用 response.status 或者 response.ok 来进行判断
response.headers.get()
,用于读取某个标头的值response.?
依据数据类型对 response 进行处理存至`第二个 .then 的参数里
response.text()
:得到文本字符串,比如 HTML 文件response.json()
:得到 JSON 对象。response.blob()
:得到二进制 Blob 对象,主要用于获取图片文件response.formData()
:得到 FormData 表单对象。response.arrayBuffer()
:得到二进制 ArrayBuffer 对象,主要用于获取流媒体文件
-
response.body
提供一个 ReadableStream 对象,其中- done 即为是否完成,value 为是一个 arrayBuffer 数组 ,表示内容块的内容,而value.length 属性是当前块的大小。可用 value.length/value 来显示读取进度
jsfetch(endpoint) .then(response => { const reader = response.body.getReader(); function readChunk() { return reader.read().then(({ done, value }) => { if (done) { return; } console.log(`Received ${value.length} bytes`); return readChunk(); }); } return readChunk(); });
reader.cancel()
用于完全结束一个流
jsfetch(endpoint) .then(res => { const reader = res.body.getReader(); return readChunk(reader); }) .then(data => { if (data) { const decoder = new TextDecoder(); const json = JSON.parse(decoder.decode(data)); console.log(json); } }) .catch(error => console.error("An error occurred: ", error)); function readChunk(reader) { return reader.read().then(({ done, value }) => { if (done) { console.log("Stream completed"); return null; } console.log("Processing data chunk..."); // 此处为条件 if (true) { console.log("Condition to stop reading met. Cancelling stream..."); reader.cancel(); return; } return value; }); }
cancel

Uncancel

感觉用处不大,了解了解......
取消 Fetch 请求
Fetch 的第二个参数可传入一些请求时的配置,其中 signal 为一个 AbortSignal 对象,可以显式指定时间取消请求

js
async function A() {
let controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 1);
try {
const response = await fetch(endpoint, {
signal: controller.signal
});
} catch (err) {
if (err.name == 'AbortError') {
console.log('Aborted!');
} else {
throw err;
}
} finally{
clearTimeout(timeoutId)
}
}
A()

正则表达式
知道了一点大概使用方法...创建正则表达式以及几个模式,用的时候再查吧

CSS效果

该说不说,这个搜索显示的条目样式还是很不错的,有种翻页的美感
核心代码

js
.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;
transition: background 0.2s;
display: flex;
justify-content: space-between;
text-transform: capitalize;
}
.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%);
}
- transition 搭配 具体的 background 使背景颜色在 2s 内完成渐变
- text-transform: capitalize 强制每个单词的首字母 转换为大写 。其他的字符保留不变
- transform 对原本正的长方形进行旋转平移配合 perspective 改变视角
- :nth-child() : odd 表示元素在兄弟元素列表中的位置是奇数,even 为偶数,还可使用 An+b
结语
主要还是通过正则表达式进行过滤替换,以及一些常用的数组方法(filter、map等),略微有点棘手
话说回来,这人可真是个天才,代码写的优雅,设计天赋也这么好😮