分享好友 站长动态首页 网站导航

初中级前端面试题(万字长文)

网友发布 2022-08-04 21:35 · 头闻号编程技术

相信大家也和我一样,2020年的春节过得非常特别。新型冠状病毒不仅对国家还是对社会以及对我们的个人都有很大影响!

很多小伙伴心里肯定想着由于种种原因,心里开始蠢蠢欲动了...

笔者通过平时面试总结以及面试别人常提的问题,结合自己认为非常重要的前端各技术栈的知识点,总结了这篇中高级前端面试。让需要的小伙伴所阅读,让不在大厂的小伙伴提前了解大厂前端面试官常问的各种常见前端问题。

文章有点长,请各位小伙伴耐心阅读完。相信认真阅读者必定或多或少有点感悟!



获取盒子宽高的几种方式及区别

dom.style.width/height

这种方式只能取到dom元素内联样式所设置的宽高,也就是说如果该节点的样式是在style标签中或外联的CSS文件中设置的话,通过这种方法是获取不到dom的宽高的


dom.currentStyle.width/height

获取渲染后的宽高。但是仅IE支持


window.getComputedStyle.width/height

与2原理相似,但是兼容性,通用性更好一些


dom.getBoundingClientRect.width/height

计算元素绝对位置,获取到四个元素left,top,width,height

扩展:

获取浏览器高度和宽度的兼容性写法:

var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidthvar h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight

Flex布局

想详细了解Flex布局知识点的小伙伴,请查看 Flex布局详解

让页面里的字体变清晰,变细用CSS怎么做

-webkit-font-smoothing在window系统下没有起作用,

但是在IOS设备上起作用-webkit-font-smoothing:antialiased是最佳的,灰度平滑

CSS常见选择器

1、CSS选择器:

2、CSS3属性选择器:

3、CSS3常见伪类选择器:

:nth-of-type:

:nth-child:

可继承的属性:font-size, font-family, color

不可继承的样式:border, padding, margin, width, height

优先级(就近原则):!important > [id > class > tag]

!important比内联优先级高

display有哪些值?说明他们的作用


BFC

一、BFC的概念?

BFC(块级格式上下文):它是页面中的一块渲染区域,有自己的渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用

二、BFC的原理?

常见的页面布局CSS3新特性常见单位

1. px:绝对单位,页面按精确像素展示2. em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值3. rem:相对单位,可理解为”root em”, 相对根节点html的字体大小来计算,CSS3新加属性,chrome/firefox/IE9+支持4. vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%5. vh:viewpoint height,视窗高度,1vh等于视窗高度的1%6. vmin:vw和vh中较小的那个7. vmax:vw和vh中较大的那个8. %:百分比

移动端视口配置

ta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> initial-scale:初始的缩放比例 minimum-scale:允许用户缩放到的最小比例 maximum-scale:允许用户缩放到的最大比例 user-scalable:用户是否可以手动缩放

文字、盒子水平垂直居中

一、行内元素水平垂直居中方法:

方式1:

text-align:center height = 100px; line-height = 100px;

方式2:

text-align:center 水平居中 display:table-cell; 垂直居中 vertical-align:middle;

二、块级元素水平居中方法:

margin:0 auto;只能设置水平居中, 而margin:auto 0 不能设置垂直居中 ,因为margin垂直塌陷问题

方法1:定位+margin

父级元素设置position:relative;儿子元素设置width: 100px; height: 100px; position:absolute; top:50%; left:50%; margin-top:-50px; margin-right:-50px; 方式2:定位方法父级元素设置position:relative;儿子元素设置position:absolute; top:0; bottom:0; left:0; right:0; margin:auto;方式3:单元格方法父级元素display:table-cell; text-align:center; vertical-align:middle; 子元素display:inline-table

Sass、Less、Stylus区别
  1. 什么事CSS预处理器
    CSS预处理器是一种语言用来为CSS增加一些变成的特性,无需考虑浏览器兼容问题,例如你可以在CSS中使用变量,简单的程序逻辑、函数等在编程语言中的一些基本技巧,可以让CSS更加简洁,适应性更强,代码更直观等诸多好处
  2. 基本语法区别
    Sass是以.sass为扩展名,Less是以.less为扩展名,Stylus是以.styl为扩展名
  3. 变量的区别
    Sass 变量必须是以$开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的。
    Less 变量是以@开头的,其余sass都是一样的。
    Stylus 对变量是没有任何设定的,可以是以$开头或者任意字符,而且变量之间可以冒号,空格隔开,但是在stylus中不能用@开头
  4. 三种预处理器都有:嵌套、运算符、颜色函数、导入、继承、混入。Stylus还有一些高级特性。例如循环、判断等
浅谈CSS响应式布局
  1. 使用@media查询可以针对不同的媒体类型定义不同的样式
  2. @media 可以针对不同的屏幕尺寸设置不同的样式,特别是如果需要设置设计响应式的页面。
  3. 重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。
    语法:@media 媒介类型 and | not | only { css 代码 } 媒介类型: print: 用于打印机和打印预览 screen: 用于电脑屏幕、平板电脑、只能手机等 all: 用于所有媒体设备类型 媒介特性: device-height: 定义输出设备的屏幕可见高度 device-width: 定义输出设备的屏幕可见宽度 height:定义输出设备中的页面可见区域高度。 width:定义输出设备中的页面可见区域宽度。 max-device-height:定义输出设备的屏幕可见的最大高度。 max-device-width:定义输出设备的屏幕可见的最大宽度。 max-height:定义输出设备中的页面可见的最大高度。 max-width:定义输出设备中的页面可见的最大宽度。 min-device-height:定义输出设备的屏幕可见的最小高度。 min-device-width:定义输出设备的屏幕可见的最小宽度。 min-height:定义输出设备中的页面可见的最小高度。 min-width:定义输出设备中的页面可见的最小宽度。
link和@import有什么区别

1. link属于html标签,除了引入css样式以外还可以定义RSS等其他事物,@import是css提供的,只能引入css2. lilnk在页面加载的时候会同时加载,@import引用的css要等页面加载结束后再加载3. link是html标签,没有兼容性,@import只有ie5以上才能识别

display: none与visibility: hidden的区别

display:none 不显示对应的元素,在文档布局中不再分配空间(回流+重绘)

visibility:hidden 隐藏对应元素,在文档布局中仍保留原来的空间(重绘)

jQueryjQuery选择器与css选择器的区别
  1. 两者的作用不同,CSS选择器找到元素后为设置该元素的样式,jQuery选择器找到元素后添加行为
  2. jQuery选择器拥有更好的跨浏览器的兼容性
  3. 两者选择器的效率不同 CSS选择器的效率:id选择器(#myid)、类选择器(.myclassname)、标签选择器(p,h1,p)、相邻选择器(h1+p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel="external"])、伪类选择器(a:hover,li:nth-child)从高到低依次排列
    jQuery选择器的效率:id选择器$和元素标签选择器$、类选择器$、属性选择器$和伪类选择器$
jQuery对象与Dom对象

$: //这种方式获取得到的就是jquery对象document.getElementById://这种方法获取到的就是dom对象

dom对象转换为jquery对象:一般情况下,dom对象直接用$就可以转换成jquery对象,如:

$)

jquery对象转换成dom对象,有两种方法,一种是用jquery的内置函数get,来获取dom对象,如:

$.get

还有一种方法更简单,因为jquery对象的属性是一个集合,所以我们可以像数组那样,取出其中一项就行:

$[0];$[5];//上面这两种返回的都是dom对象,可以直接使用js里的方法

window.onload 事件和 jQuery ready 函数有何不同JSjs基本数据类型

5个简单数据类型(基本数据类型)+ 1个复杂数据类型

undefined、number、string、null、boolean+object ES6新增Symbol

以下代码的执行结果

async function async1 { console.log; await async2; console.log; } async function async2 { console.log; } console.log; setTimeout { console.log; }, 0) async1; new Promise { console.log; resolve; }).then { console.log; }); console.log;1. 第一步,输出script start;虽然有两个函数声明,有async关键字,但是没有调用,就不看,直接打印同步代码console.log2. 第二步,输出async1 start; 因为执行async1这个函数的时候,async表达式定义的函数也是立即执行3. 第三步,输出async2; 因为async2是async定义的函数,输出async2并返回promise对象4. 第四步,输出promise1; 因为执行到new promise,promise是立即执行,就先打印promise15. 第五步,输出script end;因为上一步先打印了promise1,然后执行到resolve的时候,然后跳出promise继续向下执行,输出script end6. 第六步,输出promise2; 因为前面的nue promise放进resolve回调,所以resolve被放到调用栈执行7. 第七步,输出async1 end;因为await定义的这个promise已经执行完,并且返回结果,所以继续执行async1函数后的任务,就是console.log8. 第八步,输出setTimerout; setTimeout被放在最后被调用

如何统计网⻚上出现了多少种标签
  1. 获取所有的DOM节点

document.querySelectorAll

  1. NodeList集合转化为数组

[...document.querySelectorAll]

  1. 获取数组每个元素的标签名

[...document.querySelectorAll}.map

  1. 去重

new Set.map).size

几种判断数据类型的优缺点

一、typeof

console.log; // numberconsole.log; // booleanconsole.log; // stringconsole.log{}); // functionconsole.log;// object console.log;// objectconsole.log; // objectconsole.log;// undefined优点:能够快速区分基本数据类型 缺点:不能将Object、Array和Null区分,都返回object

二、instanceof

console.log; // falseconsole.log; // false console.log; // false console.log; // trueconsole.log{} instanceof Function);// trueconsole.log; // true优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断

三、Object.prototype.toString.call

var toString = Object.prototype.toString; console.log); //[object Number]console.log); //[object Boolean]console.log); //[object String]console.log);//[object Array]console.log);//[object Object]console.log{})); //[object Function]console.log);//[object Undefined]console.log); //[object Null]优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用

原生ajax

如何创建AjaxXMLHttpRequest对象的工作流程==========兼容性写法===========var xmlHttp = null;if { // IE7+,Firefox,Chrome,Safari,Opera xmlHttp = new XMLHttpRequset;}else { // IE5,IE6 xmlHttp = new ActiveXObject}兼容性处理事件的触发条件xmlHttp.onreadystatechange = function { if { responseText、responseXML }}事件的触发顺序======================注意=================如果是POST请求则需要添加头xmlHttp.setRequestHeader


null和undefined的区别

undefined是访问一个未初始化的变量时返回的值,而null是访问一个尚未存在的对象时所返回的值。

undefined看作是空的变量,而null看作是空的对象

DOM事件类

基本概念:DOM事件的级别(事件的本质在于信息的传递)

DOM0:element.onlick = function{} 一是在标签内写onclick事件 二是在JS写onclick=function{}函数 DOM2:element.addEventListener{},false) 三个参数分别表示为:事件名、事件处理的函数、为true则表示在捕获阶段调用,为false则表示在冒泡阶段调用 DOM3:element.addEventListener{},false) DOM事件模型:(冒泡、捕获...) 冒泡事件是从内向外;捕获是从外向内======document->html->body->p DOM事件流 一个完整的事件流分为三个阶段:捕获-》目标阶段-》冒泡=========事件通过捕获到达目标元素再从目标元素通过冒泡上传到元素 描述DOM事件捕获的具体流程 捕获:window->document->html->body->......->目标元素 冒泡:相反 Event事件的用 event.preventDefault // 阻止默认行为 event.stopPropagation // 阻止冒泡行为 event.stopImmediatePropagation // 在调用完stopPropagation函数之后,就会立即停止对后续节点的访问,但是会执行完绑定到当前节点上的所有事件处理程序;而调用stopImmediatePropagation函数之后,除了所有后续节点,绑定到当前元素上的、当前事件处理程序之后的事件处理程序就不会再执行了 event.currentTarget // 指的是绑定了事件监听的元素(可以理解为触发事件元素的父级元素) event.target // 表示当前被点击的元素 自定义事件(CustomEvent) var eve = new Event; eve.addEventListener{ console.log }) eve.dispatchEvent

对象深浅拷贝

一、深拷贝

1.1 最简单的方法就是JSON.parse) 但是这种拷贝方法不可以拷贝一些特殊的属性(例如正则表达式,undefine,function) 1.2 用递归去复制所有层级属性

function deepCopyTwo { let objClone = Array.isArray [] : {}; if { for { //判断obj子元素是否为对象,如果是,递归复制 if { objClone[key] = deepCopyTwo; } else { //如果不是,简单复制 objClone[key] = obj[key]; } } } return objClone;}二、浅拷贝 Object.assignfunction simpleClone { var result = {}; for { result[i] = obj[i]; } return result;}

想详细了解,请点击查看 对象深浅拷贝

谈谈你对Promise的理解

想详细了解,请点击查看 一步步教你实现Promise/A+ 规范 完整版

this的理解

this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象,指向window对象时可以省略不写

全局环境: this始终指向的是window对象

局部环境: 在全局作用域下直接调用函数,this指向window 对象函数调用,哪个对象调用就指向哪个对象 使用new实例化对象,在构造函数中的this指向实例化对象 使用call或apply改变this的指向

总结:this始终指向最后一个调用它的函数的对象

Class与JS构造函数的区别

1. 箭头函数不能被直接命名,不过允许它们赋值给一个变量2. 箭头函数不能用做构造函数,你不能对箭头函数使用new关键字3. 箭头函数也没有prototype属性箭头函数绑定了词法作用域,不会修改this的指向(**最大特点**)4. 箭头函数的作用域不能通过.call、.apply、.bind等语法来改变,这使得箭头函数的上下文将永久不变

ES6其他常用功能

1. let/const2. 多行字符串/模板变量3. 解构赋值4. 块级作用域5. 函数默认参数6. 箭头函数

箭头函数带来的一些问题

当你的简写箭头函数返回值为一个对象时,你需要用小括号括起你想返回的对象。否则,浏览器会把对象的{}解析为箭头函数函数体的开始和结束标记。

// 正确的使用形式 **var** objectFactory = =>

函数柯里化

// 通用版 function curry { var length = fn.length; var args = args || []; return function { newArgs = args.concat) console.log if {return curry.call; } else {return fn.apply; } } } function multiFn { console.log return a * b * c; } var multi = curry; multi // multi // multi // multi

你了解js的执行机制吗什么是单线程,和异步有何不同

单线程,只有一个线程,只能做一件事 原因:避免DOM渲染的冲突 解决方案:异步 实现方式:event-loop

什么是event-loop

事件轮询-----JS异步的解决方案 JS实现异步的具体解决方案 1、同步代码,直接执行 2、异步代码先放在 异步队列 中 3、待同步函数执行完毕,轮询执行异步队列 中的函数

自己可以实现一个new吗

一、具体实现步骤:

1. 首先函数接受不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用2. 然后内部创建一个空对象 obj3. 因为 obj 对象需要访问到构造函数原型链上的属性,所以我们通过 setPrototypeOf 将两者联系起来。这段代码等同于 obj.__proto__ = Con.prototype4. 将 obj 绑定到构造函数上,并且传入剩余的参数5. 判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 obj,这样就实现了忽略构造函数返回的原始值

二、 new操作符的特点

1. new通过构造函数Test创建处理的实例可以访问构造函数中的属性也可以访问构造函数原型链上的属性,所以:通过new操作符,实例与构造函数通过原型链连接了起来 2. 构造函数如果返回原始值,那么这个返回值毫无意义 2. 构造函数如果返回对象,那么这个返回值会被正常的使用,导致new操作符没有作用

三、new操作符的几个作用:

1. new操作符返回一个对象,所以我们需要在内部创建一个对象 2. 这个对象,也就是构造函数中的this,可以访问到挂载在this上的任意属性 3. 这个对象可以访问到构造函数原型链上的属性,所以需要将对象与构造函数链接起来 4. 返回原始值需要忽略,返回对象需要正常处理 function createNew { let obj = {} // 创建一个对象,因为new操作符会返回一个对象 Object.setPrototypeOf // 将对象与构造函数原型链接起来 // obj.__proto__ = Con.prototype // 等价于上面的写法 let result = Con.apply // 将构造函数中的this指向这个对象,并传递参数 return result instanceof Object result : obj }

bind、call、apply用法及区别

相同点: 三个函数的作用就是改变this的指向,将函数绑定到上下文中; 不同点: 三个函数的语法不同

fun.callfun.applyvar bindFn = fun.bindbindFn

扩展 :手写三个函数的源码

  1. 手写apply源码
    Function.prototype.apply = function { content.fn = this; let result; // 判断是否有第二个参数 if { result = content.fn; } else { result = content.fn; } delete content.fn; return result; }
  2. 手写call源码
    Function.prototype.call = function { // 判断是否是underfine和null // if{ // content = window // } content.fn = this; let args = [...arguments].slice; let result = content.fn; delete content.fn; return result; }
  3. 手写bind源码
    Function.prototype.bind = function { if { throw Error; } let _this = this; let args = [...arguments].slice; return function F { // 判断是否被当做构造函数使用 if {return _this.apply) } return _this.apply) } }
目前JS解决异步的方案有哪些创建对象有几种方法

// 第一种:字面量var o1 = {name: "o1"}var o2 = new Object// 第二种:通过构造函数var M = function{this.name = name}var o3 = new M// 第三种:Object.createvar p = {name: "p"}var o4 = Object.create

介绍宏任务和微任务


vue的diff算法

问题:渲染真实的DOM开销是很大的,修改了某个数据,如果直接渲染到真实dom上会引起整个DOM树的重绘和重排。

Virtual Dom 根据真实DOM生成的一个Virtual DOM,当Virtual DOM某个节点的数据改变后生成一个新的Vnode,然后Vnode和oldVnode作对比,发现有不一样的地方就直接修改在真实的DOM上,然后使oldVnode的值为Vnode.

注意:在采取diff算法比较的时候,只会在同层级进行,不会跨层级比较。

当数据发生改变时,set方法会让调用Dep.notify方法通知所有订阅者Watcher,订阅者就会调用patch函数给真实的DOM打补丁,更新响应的试图。

你有看过Element UI 的源码吗

想详细了解的小伙伴,请查看我的 从零实现一套属于自己的UI框架-发布到npm

vue-router导航守卫

一、导航守卫大体分为三类:

1. 全局守卫钩子2. 独享守卫钩子3. 路由组件守卫钩子

二、全局守卫钩子(在路由切换全局执行)

全局守卫钩子函数有三种:

const router = new VueRouter // 全局前置守卫 router.beforeEach => { // do something }) // 全局解析守卫 router.beforeResolve => { // do something }) // 全局后置守卫 router.afterEach => { // do something }) 注意: to:route即将进入的路由 from:route即将离开的路由 next:function这个是必须要调用的 next接受参数: next:直接执行下一个钩子,如果执行完了导航状态为comfirmed状态 next:中断当前导航,回到from的位置 next或next:路由到任意地址,可以携带参数等 next:会回到router.onError

三、独享守卫钩子

独享守卫是定义在单独的某一个路由里的

const router = new VueRouter => { // do something }, beforeLeave: => { // do something } } ] })

四、路由组件守卫钩子

路由组件即是在vue-router中注册的组件叫路由组件

beforeRouteEnter {} beforeRouteUpdate {} beforeRouteLeave{}

Vuex的理解及使用场景

Vuex 是一个专为 Vue 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。

1. Vuex 的状态存储是响应式的;当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新2. 改变 store 中的状态的唯一途径就是显式地提交 mutation,这样使得我们可以方便地跟踪每一个状态的变化

Vuex主要包括以下几个核心模块:

1. State:定义了应用的状态数据 2. Getter:在 store 中定义“getter”(可以认为是 store 的计算属性),就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算 3. Mutation:是唯一更改 store 中状态的方法,且必须是同步函数 4. Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作 5. Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中


其中,步骤2的具体过程是:

1. **浏览器缓存**:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求; 2. **操作系统缓存:**如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录; 3. **路由器缓存**:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存; 4. **ISP缓存:**若上述均失败,继续向ISP搜索。

重绘 & 回流
  1. DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据格式的样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称为reflow
  2. 当各个盒子的位置、大小以及其他属性,如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint
    // 触发Reflow 当你增加、删除、修改DOM节点时,会导致Reflow或Repaint 当你移动DOM的位置,或是搞个动画的时候 当你修改CSS样式的时候 当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候 当你修改网页的默认字体时 // 触发Repaint DOM改动 CSS改动 // 如何防止重排Reflow和重绘Repaint?
常见浏览器及其内核

1. -webkit-:webkit核心浏览器,Chrome2. -moz-:Gecko核心浏览器,fixfox3. -o-:Opera核心浏览器,Opera4. -ms-:微软的IE浏览器

跨域通信的几种方式

1. JSONP(只支持GET请求)2. window + hash3. window + domain4. window + name5. postMessage6. WebSocket7. CORS 跨域资源共享(所有的HTTP请求)8. nginx反向代理

性能与安全提升页面性能的方法有哪些
  1. 资源压缩合并、减少HTTP请求
  2. 非核心代码异步加载---------》异步加载的方式---------》异步加载的区别
  3. 利用浏览器缓存---------》缓存的分类-----------》缓存的原理【重点】
  4. 利用CDN
  5. 预解析DNS
    ta http-equiv="x-dns-prefetch-control" content="no"> ink rel="dns-prefetch" href="//host_name_to_prefetch.com">
前端错误类

1. 即时运行错误:代码错误;捕获方式:try...catch...、window.onerror2. 资源加载错误;object.onerror(不会冒泡 )、performance.getEntries、Error事件捕获

安全类

1. CSRF:(称为跨站请求伪造)(Cross-site request forgery)缩写CSRF2. CSRF预防措施:Token验证、Refer验证(页面来源)、隐藏令牌3. XSS缩写(cross-site scripting)跨域脚本攻击

什么是同源策略及限制

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制

源======协议+域名+端口(默认为80)源不一样就是跨域了

不同源之间不能执行以下情况,以下情况都是同源时执行:

1. cookie、LocalStorage和indexDB无法读取2. DOM无法获得3. AJAX请求不能发送

常见的兼容性问题

1. 不同浏览器的标签默认的margin和padding不一样。*{margin:0;padding:0;}​2. IE6双边距bug:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大。hack:display:inline;将其转化为行内属性。​3. 设置较小高度标签(一般小于10px),在IE6,IE7中高度超出自己设置高度。hack:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。​4. Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示,可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决。​5. 超链接访问过后hover样式就不出现了,被点击访问过的超链接样式不再具有hover和active了。解决方法是改变CSS属性的排列顺序:L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}

后记

非常喜欢的一段话:在我们20岁的时候用30岁的心态来做事,那么当我们30岁的时候就可以享受别人40岁的成功!~

最后

如果本文对你有帮助得话,给本文点个赞❤️❤️❤️

欢迎大家加入,一起学习前端,共同进步!

http://weixin.qq.com/r/MEVcRCTEzHmzrWAn9xAi

免责声明:本平台仅供信息发布交流之途,请谨慎判断信息真伪。如遇虚假诈骗信息,请立即举报

举报
反对 0
打赏 0
更多相关文章

评论

0

收藏

点赞