本文共 4117 字,大约阅读时间需要 13 分钟。
作者:©
简介: 是 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 6 篇。完整中文版指南及视频教程在 。
在输入框中搜索字或者某个词
快速匹配含有这个字或者是词的诗句。
nth-child
奇偶匹配linear-gradient
颜色渐变Array
filter()
map()
push()
join()
...
JavaScript RegExp 对象
i
、g
match()
replace()
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布局相关参考文档
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); });
具体数据请求过程见下图:
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);
获取search
和suggestions'
节点分别对change
、keyup
事件进行监听,当输入框中的内容发生变化或者键盘弹起时触发displayMatches
函数更新数据。
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, `${ this.value }`); const title = poet.title.replace(regex, `${ this.value }`); const detail_author = poet.detail_author[0].replace(regex, `${ this.value }`); // 构造 HTML 值 return `
poetrys.filter
会返回带搜索关键字的新数组。const regex = new RegExp(this.value, 'gi');
代表匹配规则。g
:执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。i
:执行对大小写不敏感的匹配。matches.map
会返回一个按照新的规则处理完以后的新的数组。title.replace(regex, "新字符串");
表示将title字符串中满足 regex
规则的字符串替换成新字符串
。简介: 资深讲师,全栈工程师;区块链、高可用架构技术爱好者。
个人博客:新浪微博:github:转载地址:http://yndfx.baihongyu.com/