学习github的开源项目
- 预览链接:http://dwz.win/95z
- 代码链接:http://dwz.win/952
-
Figma
设计稿:https://dwz.cn/mnMSVtaC
项目介绍
特点
- 移动端支持
- DIY收藏网站
- 界面简洁友好
- 使用指南
技术栈
-
Figma
-
jQuery
(BootCdn)
-
SCSS
-
parcel
实时预览
-
@media
媒体查询
-
IconFont
( iconfont.cn)
-
SVG
Symbols
- JS 事件 阻止冒泡
-
LocalStorage
-
JSON
序列化
- 哈希表
-
webpack
配置
-
Git
&GitHub
- 短链处理
- 二维码链接
后续更新
- 实现
Bing + Google
搜索
- 实现搜索 关键词 弹幕效果
Bullet Screen
- vue版本
- react版本
思路
-
Figma
作图
- 实现手机端
- 写 HTML
- 写 SCSS
- 写 JS(事件监听、DOM 操作)
- 写 HTML
- 实现PC端
- 加 媒体查询 CSS
- 写 JS(单独处理PC端逻辑)
- 加 媒体查询 CSS
- 发布到
GitHub
Gitee
实现过程
使用Figma
作图
设计稿先导:https://dwz.cn/mnMSVtaC
- 不自己配色,通用背景配色
#EEEEEE
- 常用居中操作
- 分组操作
- Alt 平移复制
- Shift 保持比例 变形
- 使用 IconFont( iconfont.cn)的图标文字,下载 PNG 图片和生成链接插入网页
- 复制 CSS 代码
手机页面 PC页面 对比参考 谷歌 Chrome 和 微软 Edge 的导航
自动标注功能可以用 摹客网的
写HTML和SCSS
实时预览
-
parcel src/index.html
meta viewport
查看大厂的
meta viewport
设置 进入chrome 开发者工具 > 移动端 > 点刷新 > 元素
-
index.html
style.scss
main.js
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
- 语义化标签
<header></header>
<main></main>
- 语义化样式类名
globalHeader
globalMain
site
siteList
lastLi
-
<form></form>
表单 搜索框
- 可以用a标签包裹div,实现点击链接
<form class="searchForm" method="get" action="https://www.baidu.com/s" target="_blank">
<input name="wd" type="text">
<button type="submit">搜索</button>
</form>
样式与布局
- reset CSS
-
flex
平均布局
-
justify-content
align-items
居中
- 谨慎加高度,内部最小的加,撑开外部的; 用
padding
使用 IconFont
- IconFont( iconfont.cn)
- 搜索关键词
plus
- 添加项目
- 查看在线链接
- 选择
Symbol
- 插入生成代码
<script src="//at.alicdn.com/t/font_1765894_oi0jnamflr.js"></script>
- 引入通用样式
<style type="text/css">
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
图片
img {max-width: 100%;max-height: 100%;}
手机端测试
- 查看 终端
ipconfig
- 获取 IP ,加上端口号
:1234
手机浏览器访问
jQuery
- 引入 jQuery CDN 加速 BootCDN
- 操作点击事件
- 用户输入 url 合法性判断
- 操作节点
const $li = $(`
<li>
<a href="${node.url}">
<div class="site">
<div class="logo">${node.logo[0]}</div>
<div class="link">${simplifyUrl(node.url)}</div>
</div>
</a>
</li>
`).insertBefore($lastLi)
哈希表(数组)的应用
- 把要添加的节点变为一种数据结构,存储,调用,渲染
main.js
const hashMap = [{
logo: 'A',
logType: 'text',
url: 'https://www.acfun.cn'
}, {
logo: './images/bilib.png',
logType: 'image',
url: 'https://www.bilibili.com'
}, {
logo: 'M',
logType: 'text',
url: 'https://developer.mozilla.org/zh-CN/'
}]// 注意用 parcel 时,默认在代码外加一层作用域 非全局变量 不用考虑全局污染
渲染函数
-
forEach
遍历生成节点添加,渲染
- 渲染 hashMap 之前必须先清空原来的
$siteList.find('li:not(.last)').remove()
const render = () => {
$siteList.find('li:not(.last)').remove()
hashMap.forEach(node => {
const $li = $(`
<li>
<a href="${node.url}">
<div class="site">
<div class="logo">${node.logo[0]}</div>
<div class="link">${simplifyUrl(node.url)}</div>
</div>
</a>
</li>
`).insertBefore($lastLi)
})
}
- 将所有对节点的操作,变为操作 hashMap 的 push 操作,渲染页面
/* 事件处理 */
$('.addButton').on('click', () => {
let url = window.prompt("请输入网址")
/* 网址合法行判断 */
if (url.indexOf("http") !== 0) {
url = 'https://' + url
}
// console.log(url)
hashMap.push({
logo: url[0],
logoType: 'test',
url: url
})
render()
}
- 优化从第二个开始渲染
hashMap.slice(2)
LocalStorage 的应用
退出网站 用户关闭网站钱触发 存到 localStorage 里
- 监听事件
window.onbeforeunload()
// 退出网站 用户关闭网站钱触发 存到 localStorage 里
window.onbeforeunload = () => {
console.log('页面要关闭了') // 可以开启 Preserve log 查看
// 将 对象变为 字符串
const string = JSON.stringify(hashMap)
// console.log(hashMap)
// console.log(typeof hashMap)
// console.log(string)
// console.log(typeof string)
}
JSON
序列化
初始时
- 在 开发者选项 Application 选项卡中可以看到
- 从 LocalStorage 中读取
const x = localStorage.getItem('x')
- 注意读取的是字符串,需要转变为对象
- 将读取的字符串 变为 对象
const xObject = JSON.parse(x)
const $siteList = $('.siteList')
const $lastLi = $siteList.find('li.last')
/* 初始时从 LocalStorage 中读取 */
const x = localStorage.getItem('x')
// 将读取的字符串 变为 对象
const xObject = JSON.parse(x)
// hashMap 初始化保底值
const hashMap = xObject || [{
logo: 'A',
logType: 'text',
url: 'https://www.acfun.cn'
}, {
logo: './images/bilib.png',
logType: 'image',
url: 'https://www.bilibili.com'
}, {
logo: 'M',
logType: 'text',
url: 'https://developer.mozilla.org/zh-CN/'
}]
退出页面时
- 退出页面时 保存 hashMap
- 将 hashMap 对象变为 字符串
const string = JSON.stringify(hashMap)
- 注意 localStorage 要保存的是字符串,需要将对象 hashMap 转变为字符串
- 保存到
localStorage.setItem('x', string)
// 退出网站 用户关闭网站钱触发 存到 localStorage 里
window.onbeforeunload = () => {
// console.log('页面要关闭了') // 可以开启 Preserve log 查看
// // 将 对象变为 字符串
const string = JSON.stringify(hashMap)
// console.log(typeof hashMap)
// console.log(hashMap)
// console.log(typeof string)
// console.log(string)
localStorage.setItem('x', string)
}
其他注意
- 清除 cookie 时 localstorage 就删除了
- 或存储硬盘满了,也可能会删除 localstorage
- 或使用无痕窗口
其他优化
- 缩短显示链接
- 处理 logo
- 简化 URL
- 删除功能
- PC 网页(媒体查询)
- PC 网页样式优化
- PC 样式影响了手机样式
- 键盘事件
缩短显示链接
const simplifyUrl = (url) => {
return url.replace('https://', '').replace('http://', '').replace('www.', '')
}
简化 URL
/* 显示链接 缩短 */
const simplifyUrl = (url) => {
return url.replace('https://', '')
.replace('http://', '')
.replace('www.', '')
}
/* <div class="link">${simplifyUrl(node.url)}</div> */
处理 logo
显示恰当的首字母
- 先去掉 logo 显示图片,直接显示字母
- 简化 去掉 logoType
- 删掉 localStorage 存储内容
- 调用
simplifyUrl(url)[0]
- 大写
simplifyUrl(url)[0].toUpperCase()
hashMap.push({
logo: simplifyUrl(url)[0].toUpperCase(),
url: url
})
- 大写也可以用 CSS 来控制
text-transform: uppercase;
显示 bug 输入长网址时 超出显示
再简化 URL
用正则表达式,表示以
/
开头的字符
const simplifyUrl = (url) => {
return url.replace('https://', '')
.replace('http://', '')
.replace('www.', '')
.replace(/\/.*/,'') // 删除以 / 开头的内容 贪婪匹配
}
删除功能
- IconFont( iconfont.cn)
- 搜索关键词
close
选择一个图标
- 添加项目
- 更新在线链接
- 选择
Symbol
- 更新代码
<script src="//at.alicdn.com/t/font_1774301_yiq4rsp0i6q.js"></script>
- 样式
hashMap.forEach(node => {
const $li = $(`
<li>
<a href="${node.url}">
<div class="site">
<div class="logo">${node.logo}</div>
<div class="link">${simplifyUrl(node.url)}</div>
<div class="close">
<svg class="icon">
<use xlink:href="#icon-close"></use>
</svg>
</div>
</div>
</a>
</li>
`).insertBefore($lastLi)
})
/*
.close{
position: absolute;
right: 10px;
top: 5px;
}
*/
- 关闭图标在a标签里,点击穿透,需要阻止冒泡
- 监听对 close 图标的点击事件
$li.on('click','.close',(e)=>{
console.log('阻止冒泡')
e.stopPropagation()
})
点击close图标,还是跳转了
- 去掉 a 标签, 用 JS 监听点击 li 标签
$li.on('click',()=>{
window.open(node.url, '_self')
})
webStorm 技巧 在变量后输入
.log
,按Tab
健,变为console.log()
这个变量
- 在 hashMap 中找到表示点击当前网站的节点,然后删掉
- 需要索引 index
- forEach() 的第二个参数为 索引 index
hashMap.forEach((node, index) => {
const $li = $(`
<li>
<div class="site">
<div class="logo">${node.logo}</div>
<div class="link">${simplifyUrl(node.url)}</div>
<div class="close">
<svg class="icon">
<use xlink:href="#icon-close"></use>
</svg>
</div>
</div>
</li>
`).insertBefore($lastLi)
$li.on('click',()=>{
window.open(node.url,'_self')
})
$li.on('click','.close',(e)=>{
// console.log('阻止冒泡')
e.stopPropagation()
// console.log(hashMap);
// console.log(index);
hashMap.splice(index,1)
render() // 删除后 重新渲染
})
})
渲染函数
/* 操作 hashMap 渲染页面 */
const render = () => {
/* 再次渲染 hashMap 之前必须先 清空原来的 */
// 找到 的除了 lastLi 之外的所有 li
$siteList.find('li:not(.last)').remove()
hashMap.forEach((node, index) => {
const $li = $(`
<li>
<div class="site">
<div class="logo">${node.logo}</div>
<div class="link">${simplifyUrl(node.url)}</div>
<div class="close">
<svg class="icon">
<use xlink:href="#icon-close"></use>
</svg>
</div>
</div>
</li>
`).insertBefore($lastLi)
$li.on('click',()=>{
window.open(node.url,'_self')
})
$li.on('click','.close',(e)=>{
// console.log('阻止冒泡')
e.stopPropagation()
// console.log(hashMap);
// console.log(index);
hashMap.splice(index,1)
render()
})
})
}
- 大部分时间处理不恰当的操作:用JS操作代替 a 标签 点击跳转、阻止冒泡
- 剩下的时间才实现最终的逻辑
PC 网页(媒体查询)
- 业界常识:PC页面的宽度是固定的
- 优先用
max-width
- 当元素有最大/小宽度(固定)时,就可以用
margin:0 auto;
来居中,但会覆盖其他元素上下margin
- 用
margin-left:auto;
margin-right:auto;
- 平均布局用负 margin
PC 网页样式优化
- 通过改变
visibility
属性来显示/隐藏关闭按钮,再通过opacity
属性的改变达到渐变的动画效果
键盘事件
- 在 document 上绑定键盘事件
将Google嵌入iframe
- 得到 chrome 插件
Double Shot Search
和 jQuery 插件 purl的启发
- 搜索
iframe src google.com
-
HTML - 如何在iframe中显示google.com?
发布到 GitHub
默认路径有问题
parcel build src/index.html --no-minify
换成
./
- 不用最小压缩,否则报错
parcel build src/index.html --no-minify --public-url ./
- 如果要构建多个
parcel build src/index.html src/search.html --no-minify --public-url ./
yarn build 一键发布
再次build的时,只需用
yarn init -y
创建package.json
- 在
package.json
中加一段脚本
"scripts": {
"build":"rm -rf dist && parcel build src/index.html --no-minify --public-url ./"
},
再次 yarn build
原则和要点
原则
- 没有移动端设计稿,绝对不要做移动端页面
- 定一个小目标来实现(短链处理)
- 没完美,做到看不出Bug
要点
- 专业的前端工程师应该能快速的抄袭大厂网页里的
meta viewport
- 前端工程师可以 flex 布局一把梭,解决 80% 以上的需求
- 将对象变成一个字符串
JSON.stringify
- 将字符串变成一个对象
JSON.parse
- 一般来说
localStorage
里的数据用户清除浏览器数据的时候消失
优秀导航网页
·未完待续·
参考链接
-
2020版前端体系课【方方】之【项目】前端导航站点(上)
-
2020版前端体系课【方方】之【项目】前端导航站点(下)
-
优秀导航网页
-
完善的输入框监听方案:兼容、高效和组合输入友好
-
js监听input输入框值的实时变化
- 作者: Joel
- 文章链接:
-
版权声明
- 非自由转载-非商用-非衍生-保持署名