美文网首页
2021-01-11

2021-01-11

作者: 4leafclover | 来源:发表于2021-01-11 19:16 被阅读0次

    html语义化标签

    什么是HTML语义化

    元素本身传达了关于标签所包含内容类型的一些信息。

    语义化的意义

    1. 代码结构: 使页面没有css的情况下,也能够呈现出很好的内容结构
    2. 有利于SEO: 爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
    3. 提升用户体验: 例如title、alt可以用于解释名称或者解释图片信息,以及label标签的灵活运用。
    4. 便于团队开发和维护: 语义化使得代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化。
    5. 方便其他设备解析: 如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页。

    语义化标签

    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
        }
    }
    

    深拷贝

    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的类有什么区别

    1. es6 class内部定义的方法都是不可枚举的
    2. es6 class必须用new调用
    3. es6 class不存在变量提升
    4. es6 class默认使用严格模式
    5. 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
    

    相关文章

      网友评论

          本文标题:2021-01-11

          本文链接:https://www.haomeiwen.com/subject/xvddaktx.html