数字马力一面

908 阅读16分钟

数字马力一面

css相关

  • 盒子模型 IE盒模型

盒模型: 在Web开发中,每个元素都被视为一个矩形的盒子,由内容区域、内边距、边框和外边距

标准盒模型:将元素的宽度和高度仅计算为内容区域的尺寸(content-box,默认)

IE盒模型:将宽度和高度包括了内边距和边框的尺寸(border-box)

box-sizing属性用于指定元素的盒模型计算方式。它有两个可能的值:content-box border-box

content-box: 它指定了盒子的宽度和高度只包括内容区域、内边距和边框,不包括外边距。 换句话说,边框和内边距的尺寸会从元素的内容区域中减去,使得内容区域的尺寸保持不变。 这可以让开发人员更轻松地控制元素的尺寸和布局,而无需考虑边框和内边距对尺寸的影响。例如,如果一个元素的宽度设置为200px,内边距设置为10px,边框设置为5px,那么元素的内容区域的宽度将为200px - 2 * 10px - 2 * 5px = 170px

border-box:它指定了盒子的宽度和高度只包括内容区域,不包括内边距、边框和外边距。 content-box 是 CSS 盒子模型的默认值,因此在不指定盒子模型属性时,浏览器会默认使用 content-box 来计算盒子的宽度和高度。 举例来说,如果一个盒子的内容宽度为 200px,内边距为 20px,边框宽度为 2px,外边距为 10px,那么 content-box 的盒子宽度计算如下: 内容宽度:200px 加上内边距:200px + 20px = 220px 加上边框:220px + 2px = 222px 加上外边距:222px + 10px = 232px

  • 内外边距重叠

外边距重叠也可以叫做外边距塌陷,即不同元素的上下外边距重叠到一起,官方解释如下:

块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则块为其中的一个),这种行为称为边距折叠。

什么情况下会出现外边距重叠情况

  1. 相邻兄弟元素之间 解决方法: 添加浮动

  2. 相邻父子(第一个子元素之间) 解决方法:

    1. 给父元素添加overflow:hidden(此方法只适用于“子元素的高度 加 上外边距高度 小于父元素高度”,不然子元素部分内容会被隐藏)
    2. 给父元素加边框border
    3. 给父级或者子级设置display:inline-block
    4. 给父级或子级设置float(会导致父元素高度塌陷问题 需清楚浮动)
    5. 给父级或者子级设置position:absolute(即将元素脱离文档流)
    6. 给父元素添加padding

外边距重叠如何计算

1 两个正数取最大的数

2 两个负数取绝对值最大的数

3 一正一负取两者之和

*BFC

BFC,即“块级格式化上下文”(Block Formatting Context),是 CSS 中一个重要的概念,它指的是一个独立的渲染区域,让块级盒子在布局时遵循一些特定的规则。BFC 的存在使得我们可以更好地控制文档流,处理浮动、清除浮动等问题。

BFC 的形成条件包括

根元素或包含它的元素

浮动元素(元素的 float 不是 none)

绝对定位元素(元素的 position 为 absolute 或 fixed)

行内块元素(元素的 display 为 inline-block)

表格单元格(元素的 display 为 table-cell)

表格标题(元素的 display 为 table-caption)

overflow 值不为 visible 的块元素

BFC 的特性包括

内部的 Box 会在垂直方向上一个接一个地放置。

Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。

每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。

BFC 的区域不会与浮动元素重叠。

BFC 在页面上是一个独立的容器,外面的元素不会影响里面的元素,反之亦然。

计算 BFC 的高度时,浮动元素也参与计算。

BFC 的应用场景包括

1、清除浮动: 当一个容器内部有浮动元素时,如果没有给容器创建 BFC,那么容器的高度将无法被撑开,导致一些问题,如边框或背景不显示、文字环绕等。可以通过在容器上创建 BFC 来解决这个问题,例如可以将容器的 overflow 设置为 hidden。

2、避免 margin 重叠: 当两个相邻的盒子都设置了 margin 时,它们之间的距离将会是两者 margin 中较大的一个,而不是将两者相加。如果将其中一个盒子放入一个 BFC 中,可以避免 margin 重叠的问题。

3、实现多栏布局: 通过创建 BFC,可以将容器划分为独立的区域,在这些区域内布局,从而实现多栏布局。

4、防止浮动元素遮盖: 当一个元素内部有浮动元素时,如果该元素没有创建 BFC,那么它的高度会缩为0,从而导致元素下面的内容被浮动元素遮盖。可以通过在元素上创建 BFC 来防止这种情况的发生。

js react vue 混合

  • js原型,原型链

原型相关

  • eventloop

事件循环是指不断从任务队列中取出任务,并执行其对应的回调函数的过程。事件循环在JavaScript引擎内部以非常高效的方式运行,在等待异步I/O操作返回数据时,可以将CPU时间释放给其他线程使用。

浅析JavaScript事件循环(Event Loop)

事件循环的基本流程如下

1.主线程执行同步任务,直到遇到异步任务时,将其回调函数添加到任务队列中,然后继续执行同步任务。
2.当所有同步任务执行完成后,主线程会立即去任务队列中查找是否有已经完成的异步任务的回调函数需要执行,如果有,则会按照回调函数添加的先后顺序执行它们。
3.执行完所有已经完成的异步任务回调函数后,重复步骤2,直到任务队列中没有任何任务。
  • https和http

应用层http和https

  • 浏览器渲染原理

原理

  • react 18 hook

react 18 hook函数详解

  • 为什么hook不能放在if中

从源码角度解析:react hook为啥不能放入条件语句中

谁说React Hooks不能放在if else里的?

  • react 组件为什么要用大写开头
babel在编译时会判断JSX中组件的首字母,当首字母为小写时,其被认定为原生DOM标签,createElement的第一个变量被编译为字符串;当首字母为大写时,其被认定为自定义组件,createElement的第一个变量被编译为对象;

  • react你在绑定click事件的时候, 这个时间是怎么被虚拟dom处理的

reac核心原理

数字马力一面

css相关

  • 盒子模型 IE盒模型

盒模型: 在Web开发中,每个元素都被视为一个矩形的盒子,由内容区域、内边距、边框和外边距


标准盒模型:将元素的宽度和高度仅计算为内容区域的尺寸(content-box,默认)

IE盒模型:将宽度和高度包括了内边距和边框的尺寸(border-box)


box-sizing属性用于指定元素的盒模型计算方式。它有两个可能的值:content-box border-box

content-box: 它指定了盒子的宽度和高度只包括内容区域、内边距和边框,不包括外边距。 换句话说,边框和内边距的尺寸会从元素的内容区域中减去,使得内容区域的尺寸保持不变。 这可以让开发人员更轻松地控制元素的尺寸和布局,而无需考虑边框和内边距对尺寸的影响。例如,如果一个元素的宽度设置为200px,内边距设置为10px,边框设置为5px,那么元素的内容区域的宽度将为200px - 2 * 10px - 2 * 5px = 170px

border-box:它指定了盒子的宽度和高度只包括内容区域,不包括内边距、边框和外边距。 content-box 是 CSS 盒子模型的默认值,因此在不指定盒子模型属性时,浏览器会默认使用 content-box 来计算盒子的宽度和高度。 举例来说,如果一个盒子的内容宽度为 200px,内边距为 20px,边框宽度为 2px,外边距为 10px,那么 content-box 的盒子宽度计算如下: 内容宽度:200px 加上内边距:200px + 20px = 220px 加上边框:220px + 2px = 222px 加上外边距:222px + 10px = 232px

  • 内外边距重叠

外边距重叠也可以叫做外边距塌陷,即不同元素的上下外边距重叠到一起,官方解释如下:

块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则块为其中的一个),这种行为称为边距折叠。

什么情况下会出现外边距重叠情况

  1. 相邻兄弟元素之间 解决方法: 添加浮动

  2. 相邻父子(第一个子元素之间) 解决方法:

    1. 给父元素添加overflow:hidden(此方法只适用于“子元素的高度 加 上外边距高度 小于父元素高度”,不然子元素部分内容会被隐藏)
    2. 给父元素加边框border
    3. 给父级或者子级设置display:inline-block
    4. 给父级或子级设置float(会导致父元素高度塌陷问题 需清楚浮动)
    5. 给父级或者子级设置position:absolute(即将元素脱离文档流)
    6. 给父元素添加padding

外边距重叠如何计算

1 两个正数取最大的数

2 两个负数取绝对值最大的数

3 一正一负取两者之和

*BFC

BFC,即“块级格式化上下文”(Block Formatting Context),是 CSS 中一个重要的概念,它指的是一个独立的渲染区域,让块级盒子在布局时遵循一些特定的规则。BFC 的存在使得我们可以更好地控制文档流,处理浮动、清除浮动等问题。

BFC 的形成条件包括

根元素或包含它的元素

浮动元素(元素的 float 不是 none)

绝对定位元素(元素的 position 为 absolute 或 fixed)

行内块元素(元素的 display 为 inline-block)

表格单元格(元素的 display 为 table-cell)

表格标题(元素的 display 为 table-caption)

overflow 值不为 visible 的块元素

BFC 的特性包括

内部的 Box 会在垂直方向上一个接一个地放置。

Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。

每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此。

BFC 的区域不会与浮动元素重叠。

BFC 在页面上是一个独立的容器,外面的元素不会影响里面的元素,反之亦然。

计算 BFC 的高度时,浮动元素也参与计算。

BFC 的应用场景包括

1、清除浮动: 当一个容器内部有浮动元素时,如果没有给容器创建 BFC,那么容器的高度将无法被撑开,导致一些问题,如边框或背景不显示、文字环绕等。可以通过在容器上创建 BFC 来解决这个问题,例如可以将容器的 overflow 设置为 hidden。

2、避免 margin 重叠: 当两个相邻的盒子都设置了 margin 时,它们之间的距离将会是两者 margin 中较大的一个,而不是将两者相加。如果将其中一个盒子放入一个 BFC 中,可以避免 margin 重叠的问题。

3、实现多栏布局: 通过创建 BFC,可以将容器划分为独立的区域,在这些区域内布局,从而实现多栏布局。

4、防止浮动元素遮盖: 当一个元素内部有浮动元素时,如果该元素没有创建 BFC,那么它的高度会缩为0,从而导致元素下面的内容被浮动元素遮盖。可以通过在元素上创建 BFC 来防止这种情况的发生。

js react vue 混合

  • js原型,原型链

原型相关

  • eventloop

事件循环是指不断从任务队列中取出任务,并执行其对应的回调函数的过程。事件循环在JavaScript引擎内部以非常高效的方式运行,在等待异步I/O操作返回数据时,可以将CPU时间释放给其他线程使用。

浅析JavaScript事件循环(Event Loop)

事件循环的基本流程如下

1.主线程执行同步任务,直到遇到异步任务时,将其回调函数添加到任务队列中,然后继续执行同步任务。
2.当所有同步任务执行完成后,主线程会立即去任务队列中查找是否有已经完成的异步任务的回调函数需要执行,如果有,则会按照回调函数添加的先后顺序执行它们。
3.执行完所有已经完成的异步任务回调函数后,重复步骤2,直到任务队列中没有任何任务。
  • https和http

应用层http和https

  • 浏览器渲染原理

原理

  • react 18 hook

react 18 hook函数详解

  • 为什么hook不能放在if中

从源码角度解析:react hook为啥不能放入条件语句中

谁说React Hooks不能放在if else里的?

  • react 组件为什么要用大写开头
babel在编译时会判断JSX中组件的首字母,当首字母为小写时,其被认定为原生DOM标签,createElement的第一个变量被编译为字符串;当首字母为大写时,其被认定为自定义组件,createElement的第一个变量被编译为对象;

  • react你在绑定click事件的时候, 这个时间是怎么被虚拟dom处理的

reac核心原理

image.png

React深入」一文吃透虚拟DOM和diff算法

  • 闭包的使用场景

深入理解闭包的概念、工作原理、应用场景和缺点

  • 事件捕获和冒泡的流程

JS事件机制浅析:事件捕获、事件冒泡和事件委托

  • ·xss 和 csrf攻击的区别

前端面试查漏补缺--(七) XSS攻击与CSRF攻击


笔试题相关

  • 实现加减乘除链式调用,类似 jQuery 式用法 输出90
console.log(myCalculator(121).add(1).minus(2).multi(3).div(4)); 

function myCalculator (x) {}
  
const obj = new myCalculator(121)
obj(121).add(1).minus(2).multi(3)

/**
 * 示例 
 * 使用原型或者class来实现链式调用
*/
class myCalculator {
    constuctor(value) {
        this.value = value
    }
    add(newvalue) {
        this.value = this.value + newvalue
        return this
    }
    reduce(newvalue) {
        this.value = this.value - newvalue
        return this
    }
    // 乘除类似
}
const obj = new myCalculator(121)
obj.add(1).minus(2).multi(3)
console.log(obj)
  • 参考: gw.alipayobjects.com/mdn/rms_efa… ,请使用 React 或 Vue 实现一个获取验证码的按钮组件,它在被点击之后,会触发 onClick 属性,并且同时进入 60s 的倒计时,在倒计时结束前,它会处于禁用状态。
<el-button @click="getCode()" :class="{'disabled-style':getCodeBtnDisable}" :disabled="getCodeBtnDisable">{{codeBtnWord}}</el-button>

data() {
     return {
        loginForm: {
            phoneNumber: '',
            verificationCode: '',
        },
        codeBtnWord: '获取验证码', // 获取验证码按钮文字
        waitTime:61, // 获取验证码按钮失效时间
    }
}

// 计算属性
computed: {
    // 用于校验手机号码格式是否正确
    phoneNumberStyle(){
        let reg = /^1[3456789]\d{9}$/
        if(!reg.test(this.loginForm.phoneNumber)){
            return false
        }
        return true
    },
    // 控制获取验证码按钮是否可点击
    getCodeBtnDisable:{
        get(){
            if(this.waitTime == 61){
                if(this.loginForm.phoneNumber){
                    return false
                }
                return true
            }
            return true
        },
        // 注意:因为计算属性本身没有set方法,不支持在方法中进行修改,而下面我要进行这个操作,所以需要手动添加
        set(){} 
    }
}

// methods
methods() {
    getCode(){
        if(this.phoneNumberStyle){
            let params = {}
            params.phone = this.loginForm.phoneNumber
            // 调用获取短信验证码接口
            axios.post('/sendMessage',params).then(res=>{
                res = res.data
                if(res.status==200) {
                    this.$message({
                        message: '验证码已发送,请稍候...',
                        type: 'success',
                        center:true
                    })
                }
            })
            // 因为下面用到了定时器,需要保存this指向
            let that = this
            that.waitTime--
            that.getCodeBtnDisable = true
            this.codeBtnWord = `${this.waitTime}s 后重新获取`
            let timer = setInterval(function(){
                if(that.waitTime>1){
                    that.waitTime--
                    that.codeBtnWord = `${that.waitTime}s 后重新获取`
                }else{
                    clearInterval(timer)
                    that.codeBtnWord = '获取验证码'
                    that.getCodeBtnDisable = false
                    that.waitTime = 61
                }
            },1000)
        }
    }
}
  • 基于fetch实现一个手动发送请求的hooks -> useManualFetch 如: const [data, loading, error, send] = useManualFetch({api: 'yyy', data: any, ...}); 默认请求不发送,在符合条件时,调用 send 手动触发请求
import React, { useState } from 'react';
function useFetchData(url, timeout) {  
    const [data, setData] = useState([]);  
    const [loading, setLoading] = useState(false)  
    const [error, setError] = useState(false)  
    function init() {    
        setData([])    
        setLoading(true)    
        setError(false)  
    }  
    async function load() { 
        init()    
        setLoading(true);    
        try {      
            const instance = axios.create();      
            const result = await instance.get(url, { timeout });      setData(result)    
        } catch (error) {      
            setError(true)    
        }    
        setLoading(false)  
    }  
    return [data, loading, error, load]
}

React深入」一文吃透虚拟DOM和diff算法

  • 闭包的使用场景

深入理解闭包的概念、工作原理、应用场景和缺点

  • 事件捕获和冒泡的流程

JS事件机制浅析:事件捕获、事件冒泡和事件委托

  • ·xss 和 csrf攻击的区别

前端面试查漏补缺--(七) XSS攻击与CSRF攻击


笔试题相关

  • 实现加减乘除链式调用,类似 jQuery 式用法 输出90
console.log(myCalculator(121).add(1).minus(2).multi(3).div(4)); 

function myCalculator (x) {}
  
const obj = new myCalculator(121)
obj(121).add(1).minus(2).multi(3)

/**
 * 示例 
 * 使用原型或者class来实现链式调用
*/
class myCalculator {
    constuctor(value) {
        this.value = value
    }
    add(newvalue) {
        this.value = this.value + newvalue
        return this
    }
    reduce(newvalue) {
        this.value = this.value - newvalue
        return this
    }
    // 乘除类似
}
const obj = new myCalculator(121)
obj.add(1).minus(2).multi(3)
console.log(obj)
  • 参考gw.alipayobjects.com/mdn/rms_efa… ,请使用 React 或 Vue 实现一个获取验证码的按钮组件,它在被点击之后,会触发 onClick 属性,并且同时进入 60s 的倒计时,在倒计时结束前,它会处于禁用状态。
<el-button @click="getCode()" :class="{'disabled-style':getCodeBtnDisable}" :disabled="getCodeBtnDisable">{{codeBtnWord}}</el-button>

data() {
     return {
        loginForm: {
            phoneNumber: '',
            verificationCode: '',
        },
        codeBtnWord: '获取验证码', // 获取验证码按钮文字
        waitTime:61, // 获取验证码按钮失效时间
    }
}

// 计算属性
computed: {
    // 用于校验手机号码格式是否正确
    phoneNumberStyle(){
        let reg = /^1[3456789]\d{9}$/
        if(!reg.test(this.loginForm.phoneNumber)){
            return false
        }
        return true
    },
    // 控制获取验证码按钮是否可点击
    getCodeBtnDisable:{
        get(){
            if(this.waitTime == 61){
                if(this.loginForm.phoneNumber){
                    return false
                }
                return true
            }
            return true
        },
        // 注意:因为计算属性本身没有set方法,不支持在方法中进行修改,而下面我要进行这个操作,所以需要手动添加
        set(){} 
    }
}

// methods
methods() {
    getCode(){
        if(this.phoneNumberStyle){
            let params = {}
            params.phone = this.loginForm.phoneNumber
            // 调用获取短信验证码接口
            axios.post('/sendMessage',params).then(res=>{
                res = res.data
                if(res.status==200) {
                    this.$message({
                        message: '验证码已发送,请稍候...',
                        type: 'success',
                        center:true
                    })
                }
            })
            // 因为下面用到了定时器,需要保存this指向
            let that = this
            that.waitTime--
            that.getCodeBtnDisable = true
            this.codeBtnWord = `${this.waitTime}s 后重新获取`
            let timer = setInterval(function(){
                if(that.waitTime>1){
                    that.waitTime--
                    that.codeBtnWord = `${that.waitTime}s 后重新获取`
                }else{
                    clearInterval(timer)
                    that.codeBtnWord = '获取验证码'
                    that.getCodeBtnDisable = false
                    that.waitTime = 61
                }
            },1000)
        }
    }
}
  • 基于fetch实现一个手动发送请求的hooks -> useManualFetch 如: const [data, loading, error, send] = useManualFetch({api: 'yyy', data: any, ...}); 默认请求不发送,在符合条件时,调用 send 手动触发请求
import React, { useState } from 'react';
function useFetchData(url, timeout) {  
    const [data, setData] = useState([]);  
    const [loading, setLoading] = useState(false)  
    const [error, setError] = useState(false)  
    function init() {    
        setData([])    
        setLoading(true)    
        setError(false)  
    }  
    async function load() { 
        init()    
        setLoading(true);    
        try {      
            const instance = axios.create();      
            const result = await instance.get(url, { timeout });      setData(result)    
        } catch (error) {      
            setError(true)    
        }    
        setLoading(false)  
    }  
    return [data, loading, error, load]
}