HTML
如何理解 HTML 中的语义化标签
- 语义化标签是一种写 HTML 标签的方法论
- 实现方法是遇到标题就用 h1 到 h6,遇到段落用 p,遇到文档用 article,主要内容用 main,边栏用 aside,导航用 nav
- 它主要是明确了 HTML 的书写规范
- 优点在于 1. 适合搜索引擎检索 2. 适合人类阅读,利于团队维护
HTML5 有哪些新标签
文章相关:header、main、footer、nav、section、article
多媒体相关:video、audio、svg、canvas
Canvas 和 SVG 的区别是什么?
- Canvas 主要是用笔刷来绘制 2D 图形的
- SVG 主要是用标签来绘制不规则矢量图的
- 相同点:都是主要用来画 2D 图形的
- 不同点
- SVG 画的是矢量图,Canvas 画的是位图
- SVG 节点多时渲染慢,Canvas 性能更好一点,但写起来更复杂
- SVG 支持分层和事件,Canvas 不支持,但是可以用库实现
CSS
BFC 是什么
BFC 是 Block Formatting Context,是块级格式化上下文。以下可以触发 BFC
- 浮动元素(float 值不为 none)
- 绝对定位元素(position 值为 absolute 或 fixed)
- inline-block 行内块元素
- overflow 值不为 visible、clip 的块元素
- 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素)
BFC 可以解决 1. 清除浮动 2. 防止 margin 合并 的问题
但是它有相应的副作用,可以使用最新的 display: flow-root 来触发 BFC,该属性专门用来触发 BFC
如何实现垂直居中
- flex
- position + transform
CSS 选择器优先级如何确定
- 选择器越具体,其优先级越高
- 相同优先级,出现在后面的,覆盖前面的
- 属性后面加 !important 的优先级最高,但是要少用
如何清除浮动
.clearfix:after {
content: '';
display: block;
clear: both;
}
两种盒模型区别
- content-box => width 和 height 只包含内容的宽和高,不包括边框和内边距。case:{width: 350px, border: 10px solid red;} 实际宽度为 370
- border-box => width 和 height 包含内容、内边距和边框。case:{width: 350px, border: 10px solid red;} 实际宽度为 350
Flex
1、flex-direction:
row、
row-reverse、
column、
column-reverse
2、flex-wrap:
nowrap
wrap
wrap-reverse
3、justify-content(主轴):
flex-start
flex-end
center
space-between
space-around
4、align-items(竖轴):
flex-start
flex-end
center
baseline(以第一行为基准线进行排列)
stretch(某个元素没有设置高度的时候,会自动充满)
5、align-content: 行与行之间的分布
flex-start
flex-end
center
space-between
space-around
strech
6、order 数字 越大越靠后 可以负数
7、flex-grow子元素分配剩余空间
8、flex-shrink子元素收缩空间
9、align-self 单独设置子元素的位置
auto
flex-start
flex-end
center
baseline
stretch
实现动画
动画基本上分类两类:补间动画和帧动画。
补间动画:补齐中间的动画。由浏览器帮助补齐中间的状态,开发者只需要定义开始和结束的状态。
帧动画:除了开始与结束状态,开发者还可以定义中间关键帧的状态,可以制作复杂的动画。
通常在前端中,实现动画的方案主要有6种:
1、javascript直接实现;
存在的问题:javascript 实现动画通常会导致页面频繁性重排重绘,消耗性能,一般应该在桌面端浏览器。在移动端上使用会有明显的卡顿。
2、SVG(可伸缩矢量图形);
SVG的一大优势是含有较为丰富的动画功能,原生绘制各种图形、滤镜和动画,并且能被js调用。html是对dom的渲染,那么svg就是对图形的渲染。3、CSS3 transition;(补间动画)
transition是过度动画。但是transition并不能实现独立的动画,只能在某个标签元素样式或状态改变时进行平滑的动画效果过渡,而不是马上改变。
4、CSS3 animation;(帧动画)
animation 算是真正意义上的CSS3动画。通过对关键帧和循环次数的控制,页面标签元素会根据设定好的样式改变进行平滑过渡。而且关键帧状态的控制是通过百分比来控制的。
5、Canvas动画;
通过getContext()获取元素的绘制对象,通过clearRect不断清空画布并在新的位置上使用fillStyle绘制新矩形内容实现页面动画效果。
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let left = 0;
let timer = setInterval(function(){
ctx.clearRect(0,0,700,550);
ctx.beginPath();
ctx.fillStyle = "#ccc";
ctx.fillRect(left,0,100,100);
ctx.stroke();
if(left>700){
clearInterval(timer);
}
left += 1;
},16);
6、requestAnimationFrame;
【1】requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,如果系统绘制率是 60Hz,那么回调函数就会16.7ms再 被执行一次,如果绘制频率是75Hz,那么这个间隔时间就变成了 1000/75=13.3ms。换句话说就是,requestAnimationFrame的执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
【2】在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
【3】requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销
将执行动画的每一步传到requestAnimationFrame中,在每次执行完后进行异步回调来连续触发动画效果。
requestAnimationFrame只是将回调的方法传入到自身的参数中执行,而不是通过setInterval调用。你要知道,无论是setInterval()还是setTimeout()都不十分精确。为它们传入的第二个参数,实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行时间。如果队列前面已经加入其他任务,那动画代码就要等前面的任务完成后再执行。
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
let elem = document.getElementById("rect");
let left = 0;
//自动执行持续性回调
requestAnimationFrame(step);
//持续该改变元素位置
function step() {
if(left<window.innerWidth-200){
left+=1;
elem.style.marginLeft = left+"px";
requestAnimationFrame(step);
}
}
总结
复杂的动画是通过一个个简单的动画组合实现的。基于兼容性问题,通常在项目中,一般在
桌面端浏览器推荐使用javascript直接实现动画或SVG方式;
移动端可以考虑使用CSS3 transition、CSS3 animation、Canvas或requestAnimationFrame方式。
DNS 解析和优化
const fs = require("fs"); const path = require("path"); const { parse } = require('node-html-parse') const { glob } = require('glob') const urlRegex = require('url-regex') const urlPattern = /(https?:\/\/[^\/]*)/i; const urls = new Set() // 遍历dist目录中所有HTML文件 async function searchDomain() { const files = await glob('dist/**/*.{html,css,js}') for (const file in files) { const source = fs.readFileSync(file, 'utf-8') const matches = source.match(urlRegex({ strict: true })) if (matches) { matches.forEach(url => { const match = url.match(urlPattern) if (match && match[1]) { urls.add(match[1]) } }) } } } async function insertLinks() { const files = await glob('dist/**/*.html') const links = [...urls].map((url) => { return `<link rel="dns-prefetch" href="${url}"/>` }).join('\n') for (const file in files) { const html = fs.readFileSync(file, 'utf-8') const root = parse(html) const head = root.querySelector('head') head.insertAdjacentHTML('aftergegin', links) fs.writeFileSync(file, root.toSting()) } } async function main() { await searchDomain() await insertLinks() } main()