前端面试笔记
常见项目难点:
1.定时器的清除
``部分动画效果需要js自动生成,时间的控制使用了timeout和innertal,其中timerout包含了innertal,点击事件和定时器不在同一个js文件中,快速来回点击的时候,定时器清除不起作用。
``解决方案:将该li对应页的所有定时器绑定在该li身上,每次点击的时候清除timeout和innertal。
2.带阴影折线运动处理
``对于倾斜的p通过js改变其高度,并且按照数学逻辑改变top和left值的情况下,p在运动时候会出现偏移,和抖动。
``解决方案:给p一个运动基准点,这样p在运动的时候就无需改变top和left值,只需要改变宽度或高度即可。
3.抛物线的运动
``css中两个点运动都是直线运动。
``解决方案:给初始点一个旋转角度,这样看起来就有抛物线的感觉。
4.遮罩层处理
``在多层级的html渲染中,中间图层的遮罩效果无法实现。
``解决方案:遮罩层可以在最底层使用,但是中间层级的遮罩效果需要对图片进行处理,改成png图片,再进行css操作。
5.卡顿的处理
``在Firefox和ie中,小图标的缓慢移动效果会出现卡顿。
``解决方案:给运动时间的时候,判断如果不是chrome浏览器,减小运动时间。
6.性能的优化
``图片的使用让动画加载的速度变慢,影响用户体验。
``解决方案:对部分能使用p代替的图片采用p生成,对代码,图片进行深度压缩上传等。
未复习目录:
- vue 路由科学配置,vuex
- 延迟加载,
- 正则
复习知识点:
闭包:
JavaScript的闭包
闭包简单的说就是一个函数能访问外部函数的变量,这就是闭包
(闭包的三大特点为:
1、函数嵌套函数
2、内部函数可以访问外部函数的变量
3、参数和变量不会被回收。
手写个简单的闭包:
function bibao(){
var a = '闭包一';
return function(){
console.log(a)
}
}
bibao()
ajax:
实现原理:网页DOM对象可以精确地对网页中的部分内容进行操作、XML作为单纯的数据存储载体使得客户端与服务器交换的只是网页内容的数据而没有网页样式等等的附属信息、XMLHttpRequest是与浏览器本身内置的request相互独立的与服务器交互的请求对象。
面试题(附加知识点):
-
xml和html的区别:
XML 被设计用来传输和存储数据。
HTML 被设计用来显示数据。
-
js倒计时。
-
活动页面的特效。
-
js es6, js es5
-
兼容性:加一些浏览器内核头。
-
vue 组件传值。(props父传子,$.emit子传父)
-
微信小程序接口。
面试复习:
9-17:
js dom节点操作:
//速记:
queryselectorAll('.div1')
getElementById("div1") //找
createElement("p") //建
b.appendChild(a) //加 把a添加到b中
b.removeChild(a) //删 从b中删除a
replaceChild(newnode,oldnode) //换
.cloneNode(true) //克隆 true包括后代
.innerHTML= //改内容
.style.属性= //改样式
.onclick=function() //事件
var para=document.createElement("p"); //创建节点
var node=document.createTextNode("这是新段落。"); //创建文本节点
para.appendChild(node); //添加节点
var element=document.getElementById("div1"); //获取节点
element.appendChild(para);
var parent=document.getElementById("div1"); //获取父节点
var child=document.getElementById("p1"); //获取子节点
parent.removeChild(child); //删除
// 快捷删除(child.parentNode找到父节点)
var child=document.getElementById("p1");
child.parentNode.removeChild(child); //找到父节点并删除其子child节点
document.getElementById(id).innerHTML=new HTML //改变内容
document.getElementById(id).style.property=new style//改样式
document.getElementById("myBtn").onclick=function(){displayDate()}; //添加事件
//替换节点:
var newnode = document.createElement("li"); //创建新节点
var oldnode = document.getElementById("oldnode"); //获取老节点
parentNode // 父节点
newnode.innerHTML = oldnode.innerHTML; //复制内容
oldnode.parentNode.replaceChild(newnode,oldnode); //替换
//克隆节点
var main=document.getElementById("main");
var box=document.getElementById("box");
var newNode=box.cloneNode(true); //true时包含子节点,false时不克隆子节点。
main.appendChild(newNode);
css 清除浮动的方法:
-
最完美方法,加带clear的伪元素:
.news { background-color: gray; border: solid 1px black; } .news img { float: left; } .news p { float: right; } .clearfix:after{ content: "020"; display: block; height: 0; clear: both; visibility: hidden; } .clearfix { /* 触发 hasLayout */ zoom: 1; }
<div class="news clearfix">
<img src="news-pic.jpg" />
<p>some text</p>
</div>
通过CSS伪元素在容器的内部元素最后添加了一个看不见的空格"020"或点".",并且赋予clear属性来清除浮动。需要注意的是为了IE6和IE7浏览器,要给clearfix这个class添加一条zoom:1;触发haslayout。
-
使用带clear属性的空元素:
在浮动元素后使用一个空元素如
,并在CSS中赋予.clear{clear:both;}属性即可清理浮动。亦可使用
或
来进行清理。 -
使用CSS的overflow属性
给浮动元素的容器添加overflow:hidden;或overflow:auto;可以清除浮动,另外在 IE6 中还需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1。
元素居中方法:
-
非块级元素水平居中(例如图片、文字) 父元素:text-align: center;
-
块级元素水平居中, margin:0 auto;
-
单行文本的垂直居中,让 line-height 和 height 相等。
-
确定高度的块级元素垂直居中,使用 position: absolute; top: 50%; margin-top: ...;(margin-top的值为自身高度的值的一半的负值);
-
绝对定位实现水平垂直居中,使用 position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto;
-
不确定元素大小,浮动加平移实现水平垂直居中法,添加:
position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
添加厂商前缀 -webkit- 兼容 Safari 和 Chrome -
确定大小的块级元素水平垂直居中,假设元素大小为100*100,则:
position: absolute;top: 50%;margin-top: -50px;left: 50%;margin-left: -50px
-
css3伸缩布局实现元素水平垂直居中,父元素设置display:flex; align-items: center; justify-content: center;
-
让浏览器计算子元素的宽高并让其水平垂直居中:通过使用定位position: absolute; top:...; right: ...; bottom: ...; left: ...; 四个方向上的值缺一不可。
<div class="parent-box"> <div class="child-box">让浏览器计算子元素的宽高并让其水平垂直居中</div> </div> .parent-box { position: relative; width: 200px; height: 200px; background-color: #f00; } .child-box { position: absolute; top: 20%; right: 20%; bottom: 20%; left: 20%; background-color: #f54; }
-
get,post 请求的区别,请求到的数据分别放在哪http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
-
canvas
9-18:
-
Ajax解析json:(从后台获取的是json字符串,所以用第一种方法解析)
var obj =JSON.parse( str)
或var obj = str.parseJSON()
json字符串转成json对象var str=JSON.stringify(obj) 或 var str=obj.toJSONString()
json对象转成json字符串
9月19:
1、js数据的存储方式和区别:
https://www.cnblogs.com/hjt-7/p/6401050.html
sessionStorage
localStorage
cookie
2、js中new()到底做了些什么?
https://www.cnblogs.com/faith3/p/6209741.html
要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4 个步骤:
(1) 创建一个新对象;
(2) 将旧对象构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) ;
(3) 执行构造函数中的代码(为这个新对象添加属性) ;
(4) 返回新对象。
3、js合并对象:
var hua = {a:'aa',b:'bb'}
var hua2 = {c:'cc',d:'dd',b:'bbb'}
var hua3 = {dd:'66'}
// var hua4 = Object.assign(hua,hua2,hua3)
console.log(hua4,hua,hua2,hua3) //注意观察,会污染第一个被合并的对象
// 解决方法:让第一个被合并的对象是空对象
var hua4 = Object.assign({},hua,hua2,hua3)
console.log(hua4,hua,hua2,hua3)
大块知识点:
继承:
// 父类:
function funpar(){
this.a = 'aa'
this.fun1 =function(){
console.log('fun1')
}
}
//父类原型链:
funpar.prototype.hello ='hello'
funpar.prototype.sayhello=function(){
console.log(this.hello)
}
par = new funpar() //父类的某个对象
console.log('par:',par)
//继承要在创建子对象时进行
// 方法一:对象冒充
var funchi = function(){
this.c = 'cc'
this.cfun = function(){
console.log('cfun')
}
this.mm=funpar; //继承是 创建函数 的继承
this.mm();
delete this.mm;
}
chi = new funchi()
console.log('chi:',chi)
// 方法二:call(),apply()
var funchi2 = function(){
this.c2 = 'c2'
this.c2fun = function(){
console.log(this.c2)
}
funpar.call(this,'aa')
// funpar.apply(this,['aa'])
}
var chi2 = new funchi2()
console.log('chi2',chi2)
//方法三:原型链继承:
var funchi3 = function(){
funchi3.prototype = new funpar()
// funchi3.prototype = funpar.prototype ?有何区别?
}
var chi3 = new funchi3()
console.log('chi3',chi3)
// 方法四:混合继承
//继承实例
var funchi4 =function(){
funpar.call(this)
}
//继承原型链
funchi4.prototype = new funpar()
var chi4 = new funchi4()
console.log('chi4',chi4)
// 方法五:寄生组合继承(要会手写)
//一样先继承实例
function funchi5(){
funpar.call(this)
this.cc5 = 'cc5'
}
//寄生的方法继承原型链
(function(){
var ls = function(){} //创建一个空类
ls.prototype = funpar.prototype; //将父原型寄生给空类
funchi5.prototype = new ls() //通过继承空类达到继承父类的目的
})()
var chi5 = new funchi5()
console.log('chi5:',chi5)
推荐使用寄生组合继承,因为它解决了前面几种继承方式的:只能继承实例,只能继承原型,不能多继承,要创建出两份实例 等缺点。
数组:
http://www.runoob.com/jsref/jsref-obj-array.html
数组属性
属性 | 描述 |
---|---|
constructor | 返回创建数组对象的原型函数。 |
length | 设置或返回数组元素的个数。 |
prototype | 允许你向数组对象添加属性或方法。 |
Array 对象属性
方法 | 描述 |
---|---|
concat() | 连接两个或更多的数组,并返回结果。var arr3 =arr.concat(arr2) |
copyWithin() | 从数组的指定位置拷贝元素到数组的另一个指定位置中。 |
entries() | 返回数组的可迭代对象。 |
every() | 检测数值元素的每个元素是否都符合条件。 |
fill() | 使用一个固定值来填充数组。 |
filter() | 检测数值元素,并返回符合条件所有元素的数组。 |
find() | 返回符合传入测试(函数)条件的数组元素。 |
findIndex() | 返回符合传入测试(函数)条件的数组元素索引。 |
forEach() | 数组每个元素都执行一次回调函数。 |
from() | 通过给定的对象中创建一个数组。 |
includes() | 判断一个数组是否包含一个指定的值。 |
indexOf() | 搜索数组中的元素,并返回它第一次出现的位置。 |
isArray() | 判断对象是否为数组。 |
join() | 把数组的所有元素放入一个字符串。 |
keys() | 返回数组的可迭代对象,包含原始数组的键(key)。 |
lastIndexOf() | 返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。 |
map() | 通过指定函数处理数组的每个元素,并返回处理后的数组。 |
pop() | 删除数组的最后一个元素并返回删除的元素。 |
push() | 向数组的末尾添加一个或更多元素,并返回新的长度。 |
reduce() | 将数组元素计算为一个值(从左到右)。 |
reduceRight() | 将数组元素计算为一个值(从右到左)。 |
reverse() | 反转数组的元素顺序。 |
shift() | 删除并返回数组的第一个元素。 |
slice() | 选取数组的的一部分,并返回一个新数组。 |
some() | 检测数组元素中是否有元素符合指定条件。 |
sort() | 对数组的元素进行排序。 |
splice() | 从数组中添加或删除元素。 |
toString() | 把数组转换为字符串,并返回结果。 |
unshift() | 向数组的开头添加一个或更多元素,并返回新的长度。 |
valueOf() | 返回数组对象的原始值。 |
1、arrayobj.sort([fun(a,b)])
此方法将 Array 对象进行适当的排序;在执行过程中并不会创建新的 Array 对象。
fun(可选参数):fun是用来确定元素顺序的函数的名称 , 如果这个参数被省略,那么元素将按照 ASCII 字符顺序进行升序排列。fun(a,b) 两个参数,分别代表每次排序比较时的两个数组项。sort()排序时每次比较两个数组项都回执行这个参数,并把两个比较的数组项作为参数传递给这个函数。当函数返回值为大于1的时候就交换两个数组项的顺序,否则就不交换。
-
扩展:
// JS随机打乱数组 function randomsort(a, b) { return Math.random()>.5 ? -1 : 1; //用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1 } var arr = [1, 2, -3, -4, 5,8,7,5]; arr.sort(randomsort); console.log(arr) //[1, 2, -4, -3, 7, 8, 5, 5]随机
// sort实现降序排序 //方法一: var arr = [1, 2, -3, -4, 5,8,7,5]; function jian(a,b){ return a>b ? -1 : 1; // 或 return a-b 升序 //return b-a 降序 } arr.sort(jian) console.log(arr) //[8, 7, 5, 5, 2, 1, -3, -4] //方法二:(有待确认) var arr = [1, 2, -3, -4, 5,8,7,5]; arr.sort() //先排序 console.log(arr) //[-3, -4, 1, 2, 5, 5, 7, 8] function dao(a,b){ return 1 } arr.sort(dao) //再反转,相当于reverse() console.log(arr) //[8, 7, 5, 5, 2, 1, -4, -3] arr.reverse() console.log(arr) //[-3, -4, 1, 2, 5, 5, 7, 8]
2、数组和对象的遍历:forEach ,map , for in , for of
https://www.cnblogs.com/yizhilin/p/7344675.html
3、reduce 方法:https://blog.csdn.net/yihanzhi/article/details/78595325
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
4、过滤filter()
filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。
filter()基本语法:
arr.filter(callback[, thisArg])
/*
filter()实例:筛选排除掉所有的小值
下例使用 filter 创建了一个新数组,该数组的元素由原数组中值大于 10 的元素组成。
*/
function isBigEnough(element) {
return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
console.log(filtered);//[ 12, 130, 44 ]
5、计算数组中某个元素的个数(以5为例)
// 方法一:遍历
var arr = [1, 2, -3, -4, 5,8,7,5,5,5];
var count = 0
arr.forEach(function(value,index){
if(value==5){
count=count+1
}
})
console.log(count) //4
// 方法二:过滤
function count2(element){
return element==5
}
var arr2 = arr.filter(count2)
console.log(arr2.length); //4
6、数组去重
//方法一
var arr = [1,23,1,1,1,3,23,5,6,7,9,9,8,5];
function removeDuplicatedItem(arr) {
for(var i = 0; i < arr.length-1; i++){
for(var j = i+1; j < arr.length; j++){
if(arr[i]==arr[j]){
8 arr.splice(j,1);//console.log(arr[j]);
j--;
}
}
}
return arr;
}
arr2 = removeDuplicatedItem(arr);
console.log(arr);
console.log(arr2);
//方法二
//借助indexOf()方法判断此元素在该数组中首次出现的位置下标与循环的下标是否相等
var ar = [1,23,1,1,1,3,23,5,6,7,9,9,8,5];
function rep2(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) != i) {
arr.splice(i,1);//删除数组元素后数组长度减1后面的元素前移
i--;//数组下标回退
}
}
return arr;
}
var a1 = rep2(ar);
console.log(ar);
console.log(a1);
//方法三 利用数组中的filter方法
var arr = ['apple','strawberry','banana','pear','apple','orange','orange','strawberry'];
var r = arr.filter(function(element,index,self){
return self.indexOf(element) === index;
});
console.log(r);
// 利用es6的set去重:
var arr=[2,2,2,3,3,4,55,5,55]
const set = new Set(arr)
console.log(set)
arr = Array.from(set) //Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例。
console.log(arr)
兼容性问题:
1、不同浏览器的标签默认的外补丁( margin )和内补丁(padding)不同
解决方案: css 里增加通配符 * { margin: 0; padding: 0; }
2、IE6双边距问题;在 IE6中设置了float , 同时又设置margin , 就会出现边距问题
解决方案:设置display:inline;
3、当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度
解决方案:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度
4、图片默认有间距
解决方案:使用float 为img 布局
5、IE9以下浏览器不能使用opacity
解决方案:
opacity: 0.5;filter: alpha(opacity = 50);filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);
6、边距重叠问题;当相邻两个元素都设置了margin 边距时,margin 将取最大值,舍弃最小值;
解决方案:为了不让边重叠,可以给子元素增加一个父级元素,并设置父级元素为overflow:hidden;
7、cursor:hand 显示手型在safari 上不支持
解决方案:统一使用 cursor:pointer
8、两个块级元素,父元素设置了overflow:auto;子元素设置了position:relative ;且高度大于父元素,在IE6、IE7会被隐藏而不是溢出;
解决方案:父级元素设置position:relative
vue:
vue的特性:
Vue.js的特点:MVVM框架、数据驱动、组件化、轻量、简洁、高效、快速、模块友好
vue的mixin:(混合组件)
普通组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,单本质上两者还是泾渭分明,相对独立。
而mixins则是在引入组件之后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。
单纯组件引用:
父组件 + 子组件 >>> 父组件 + 子组件
mixins:
父组件 + 子组件 >>> new父组件
- vue提高性能
- vue异步加载路由
- vue虚拟dom的优劣
- Vue和其他框架对比
- 原生和jQuery对象的转换
- 静态demo实现响应式
vue-loader:
Vue-Resource
主要用于发送ajax请求,官网已经不在维护(推荐axios)
html基础:
行内元素,块级元素与空元素
行内元素:a、b、span、img、input、strong、select、label、em、button、textarea
块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote
空元素:br 换行、meta 头部元信息、hr 水平线、link 链接外部样式、input、img
css:
CSS选择器:
基本可以分为通配选择器,标签选择器,类选择器,ID选择器,属性选择器。从结构上来分还有后代选择器,子元素选择器,相邻兄弟选择器以及伪类。
CSS3新增伪类汇总:https://blog.csdn.net/qq_28506819/article/details/72846680
css画三角形:
.sanjiao{
width:0;
height:0;
border-width:0px 0px 30px 30px;
border-style:solid;
border-color: transparent transparent transparent #333;
}
ajax/axios:
手写 $ajax:
$.ajax({url:"demo_test.txt",success(result){
$("#div1").html(result+status);
},error(xhr,status,error){
$("#div1").html(error);
}});
性能/兼容性:
提高页面加载速度(性能):
https://blog.csdn.net/wsymcxy/article/details/82377355
- 减少请求,使ajax可缓存(能用get就不要用post)
- 压缩资源(包括图片,js,css,组件等文件)
- 减少整页刷新和重定向
- 使用外部的JavaScript和CSS(外联文件,浏览器可能缓存它们)
- 合理使用CDN分发。