html语义化标签
什么是HTML语义化
元素本身传达了关于标签所包含内容类型的一些信息。
语义化的意义
- 代码结构: 使页面没有css的情况下,也能够呈现出很好的内容结构
- 有利于SEO: 爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
- 提升用户体验: 例如title、alt可以用于解释名称或者解释图片信息,以及label标签的灵活运用。
- 便于团队开发和维护: 语义化使得代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化。
- 方便其他设备解析: 如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页。
语义化标签
header、footer
nav、article
aside:定义与主要内容相关的内容块。通常显示为侧边栏。
section:元素用于标记文档的各个部分,例如长表单文章的章节或主要部分。
small:为较不重要的内容定义小字体。如果被包围的字体已经是字体模型所支持的最小字号,那么 <small> 标签将不起任何作用。
px,em,rem区别
「px」 相对长度单位,是相当于显示器的分辨率而言的「em」 相对长度单位,相对父元素的字体大小而言的「rem」 相对长度单位,相对html根元素的字体大小而言的,css3新增元素
盒子模型
「IE盒子模型」 宽度=内容宽度+padding *2+border *2「w3c盒子模型」 宽度=内容宽度 通过box-sizing切换,默认为content-box(w3c盒子模型),border-box时为IE盒子模型
BFC(Block Formatting Context)
块级格式化上下文,让BFC里面的元素与外面元素隔离,使里外元素的定位不会相互影响。
触发条件:
根元素
overflow不为visible
float
position:absolute或fixed
display:inline-block或table
应用:
防止垂直方向margin重叠
不和浮动元素重叠
清除元素内部浮动
[BFC详解: https://www.cnblogs.com/chen-cong/p/7862832.html]
target和currentTarget区别
target是事件触发的真实元素
currentTarget是事件绑定的元素
(专业描述:target是事件的真正目标 currentTarget是事件处理程序注册的元素)
document.ready和window.onload区别
document.ready是dom树加载后执行(不包含图片等非文字媒体文件)。
window.onload是整个页面资源(图片等文件)加载完后执行。
所以document.ready比window.onload先执行
事件流
DOM2事件流分为三个部分:事件捕获、处于目标、事件冒泡。
绑定事件之后,当用户触发到某元素的事件之时,则会从document开始一级一级的向下查找到对应的元素,该阶段为捕获阶段;到达目标之后则为目标阶段;触发目标的处理程序之后,则从目标一级一级的向上直到document,该阶段为冒泡阶段。
如今一般都是使用冒泡事件流来进行事件的处理;
「事件冒泡」是指事件从执行的元素开始往上层遍历执行
「事件捕获」是指事件从根元素开始从外向里执行
点击按钮后,
事件冒泡的执行顺序是:button->body->html->document
事件捕获的执行顺序则相反:document->html->body->button
[事件流:https://www.cnblogs.com/Yoriluo/p/6783378.html]
doctype作用,严格模式和混合模式的区别
<!doctype>声明位于文档的最前面,在html之前显示。用于告诉浏览器的解析器,用什么文档类型规范来解析文档。 严格模式默认用浏览器支持的最高版本解析,混合模式以宽松的向后兼容的方式解析,doctype不存在或格式不正确时会让文档以混杂模式呈现
水平垂直居中
//方法一
display:flex;
justify-content:center;
align-items:center;
//方法二
display:table;
vertical-align:center;
//方法三:适用于已知宽高且父元素定位不为static
postion:absolute;
width:100px;
height:100px;
top:50%;
left:50%;
margin:-50px 0 0 -50px;
//方法四
position:absolute;
top:50%;
left:50%;
transform:translateY(-50%) translateX(-50%);
//方法五:适用于行内元素
display:inline-block;
width:100px;
height:100px;
text-align:center;
line-height:100px;
//方法六:适用于块级元素
display:block;
height:100px;
margin:0 auto;
line-height:100px;
回流和重绘区别
回流:当渲染树中元素尺寸、结构或者某些属性发生变化时,浏览器重新渲染部分或全部页面的情况叫回流。 下列元素改变引发回流:
- getBoundingClientRect()
- scrollTo()
- scrollIntoView()或者scrollIntoViewIfneeded
- clientTop、clientLeft、clientWidth、clientHeight
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- getComputedStyle()
重绘:当页面中元素样式变化不会改变它在文档流中的位置时,即不会使元素的几何属性发生变化,浏览器会将新样式赋给它并重新绘制页面(比如color、backgroundColor)
频繁回流和重绘会引起性能问题
避免方法:
- 减少table布局使用
- 减少css表达式的使用(如calc())
- 减少DOM操作,用documentFragment代替
- 将元素设为display:none;操作结束后把它显示回来,因为display:none不会引发回流重绘
- 避免频繁读取会引发回流重绘的元素,如果需要最好是缓存起来
- 对复杂动画元素使用绝对定位,使它脱离文档流
- 减少使用行内样式
setTimeout、setInterval区别
两者都是定时器,设定一个150ms后执行的定时器不代表150ms后定时器会执行,它表示代码在150ms内会被加入队列,如果这个时间点队列没有其他逻辑在执行,表面上看代码在精确时间执行了。在队列中有其他逻辑时,代码等待时间会超过150ms「setTimeout」 只执行一次「setInterval」 执行多次,属于重复定时器
防抖节流
节流:多次触发事件时,一段时间内保证只调用一次。以动画为例,人眼中一秒播放超过24张图片就会形成动画,假设有100张图片,我们一秒播放100张过于浪费,一秒播放24张就够了。 防抖:持续触发事件后,时间段内没有再触发事件,才调用一次。以坐电梯为例,电梯10s运行一次。如果快要运行时进来一个人,则重新计时。
//节流
function throttle(fn,delay) {
let timer=null
return function () {
if(!timer){
timer=setTimeout(()=>{
fn.call(this,arguments)
timer=null
},delay)
}
}
}
//防抖
function debounce(fn,delay) {
let timer=null
return function () {
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()=>{
fn.call(this,arguments)
},delay)
}
}
深浅拷贝
浅拷贝:
- concat()
- Object.assign()
- slice()
- 手写
function shallowCopy() {
if (typeof obj !=='function'&& obj!==null) {
let cloneObj = Array.isArray(obj) ? [] : {}
for (let prop in obj) {
cloneObj[key] = obj[prop]
}
return cloneObj
} else {
return obj
}
}
深拷贝
- JSON.stringfy(JSON.parse())
- [hasOwnProperty: https://www.cnblogs.com/weiqinl/p/8683207.html]
function deepClone(obj) {
let objClone = obj instanceof Object ? [] : {}
if (obj && typeof obj === 'object') {
for(let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
objClone[key] = deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
}
return objClone
}
继承
了解的es6新特性
说的越多越好,比如Promise,箭头函数、数组扩展:includes()、find()、findIndex()...,Symbol、Map、Set... 看阮一峰的ES6就好了
es6的class的es5的类有什么区别
- es6 class内部定义的方法都是不可枚举的
- es6 class必须用new调用
- es6 class不存在变量提升
- es6 class默认使用严格模式
- es6 class子类必须在父类的构造函数中调用super(),才有this对象;而es5是先有子类的this,再调用父类的方法应用再在this上面
数组去重
function filterArr() {
return new Set(arr)
}
function filterArr2(arr) {
let newArr = arr.filter((item, index)=>{
return arr.indexOf(item)===index
})
console.log(newArr)
}
function filterArr3(arr) {
let isRepeat, newArr=[];
for(let i = 0; i < arr.length; i++) {
isRepeat = false
for (let j = 0; j < arr.length; j++) {
if (arr[i] === arr[j]) {
isRepeat = true
}
}
if (!isRepeat) {
newArr.push(arr[i])
}
}
return newArr
}
function filterArr4(arr) {
let seen = {}
return arr.filter((item)=>{
return seen.hasOwnProperty(item) ? false : (seen[item]=true)
})
}
function filterArr5(arr) {
let lastArr = []
const newArr = arr.sort((a,b)=>{
return a-b
})
for(let i = 0; i < newArr.length; i++) {
if (newArr[i] !=== newArr[i+1) {
lastArr.push(newArr[i])
}
}
return lastArr
}
this
this绑定函数的执行上下文,谁调用它,它就指向谁。分为默认绑定、显式绑定、隐式绑定、apply/call/bind绑定、new绑定和箭头函数绑定。
默认绑定:严格模式下this指向undefined,非严格模式this指向window
function foo() {
console.log(this.a)
}
var a=2
foo()
执行结果是什么?显然是2,此时使用的默认绑定规则(非严格模式),this指向的是window,因此调用this.a等于调用window.a,输出结果2。如果使用严格模式,结果又会是什么?
function foo() {
'use strict'
console.log(this.a)
}
var a=2
foo()
此时this不再指向window,而是undefined,因此调用this.a会抛出一个错误,Cannot read property 'a' of undefined
隐式绑定 下面这段代码的输出是什么?
function foo() {
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
obj.foo()
当foo函数被调用时,它被obj对象拥有,因此输出2
注意:对象引用只有最后一层会影响调用位置
function foo() {
console.log(this.a)
}
var obj2={
a:42,
foo:foo
}
var obj1={
a:2,
obj2:obj2
}
obj1.obj2.foo()//42
call、apply、bind都可以改变this的指向,但是apply接收参数数组,call接收的是参数列表 bind接收的是参数列表,但是apply和call调用就执行,bind需要手动执行 箭头函数绑定:箭头函数的this是父作用域的this,不是调用时的this,其他方法的this是动态的,而箭头函数的this是静态的
window.name='a'
const obj={
name:'b',
age:22,
getName:()=>{
console.log(this)
console.log(this.name)
},
getAge:function(){
setTimeout(()=>{
console.log(this.age)
})
}
}
obj.getName();//window a
obj.getAge();//22