1. 开发时遇到的兼容性问题
(*) 标准的绑定事件方法是addEventListener,IE是AttachEvent。
(1) ios的点击300ms延迟问题。解决办法:禁用缩放=》页面设置user-scalable = no或者引入fastClick库。
(2) 图片默认有边距。解决办法:使用float为img布局
(3) 浮动的有margin元素会导致双margin。解决:display:block。
(4) IE6下使用margin: 0 auto无法居中。解决:父元素设置text-align: center。
(5) 被点击过的链接不再有hover和active属性。解决: 按照lvha的顺序写css样式。
(6) 使用定位后,IE设置z-index失效。原因:父元素默认层级是0.
(7) IE对有些媒体查询等样式不支持,所以使用条件注释。
<!--[if lt IE 7]> 此处内容只有IE7.0可见<![endif]-->
2. css3新属性,比如动画,flex
animation: ani1 100ms linear ;
@keyframes 动画名 {
from {
transform: translate(0, 0);
}
to{
transform: translate(0,100px);
}
}
符号选择器
:选择前者的所有后者子选择器
+:选择紧邻在前者的后一个兄弟节点
~:选择前者元素之后的所有后者兄弟节点
p: nth-child(n):选择父元素里第n个是p的元素
:nth-of-type(odd):选择奇数位元素
:nth-of-type(even):选择偶数位元素
3. 垂直居中
(1)父元素display: table-cell,text-align:center,verticle-align:middle。
(2)父元素display: flex,justify-content:center,align-item: center。
(3)绝对定位和负边距。(此情况需要知道子元素具体宽高)
父{
position: relative;
}
子{
position : absolute;
top:50%;
left: 50%;
margin-left: 子元素宽度的50%;
margin-top: 子元素宽度的50%;
}
(4)绝对定位和transform
父{
position: relative ;
}
子{
position:absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
4. vuex,webpack的plugin和loader,路由,vue双向数据绑定原理等
5. sass
混合宏: @mixin指令介绍
(1) 定义mixin:使用@mixin 名称的方式就可以定义一个mixin模块,里面加上所要的样式,并且可以传参
@mixin button($background : green) { //green是默认值,可以不设默认值
width:100px;
height: 30px;
background: $background;
}
(2) 使用mixin:使用@include 名称可以调用mixin
@include button($background)
@extend可以继承已存在的类样式块
.btn {
background: red;
}
.btn-primary {
@extend .btn;
}
控制命令@if
@if $blloean {
display: block;
}
css函数如calc(), min(), max(), floor()
calc()函数里如果想插入变量,需要用#{}包裹一下
$rightWidth: 100px;
calc(100%- #{$rightWidth})
6.原型链
原型链原理
每一个函数在创建的时候会有一个prototype得到属性指向这个函数的原型,而这个原型对象上也会有一个constructor的属性指向构造函数,原型链的顶端是Object.prototype。
new Foo()的时候发生了什么:
a. 创建一个新的空对象实例
b. 将此空对象的原型指向构造函数的原型
c. 执行构造函数,同时this指向这个新实例
d. 如果返回值是一个新对象,那就直接返回这个对象,如果不是,就将步骤1创建的对象返回。
创建对象的几种方法:
a. 对象字面量创建
b. new Object
c. 构造函数创建
d. Object.create(obj,{
name: ‘andi’
})
继承的几种方法:
a. 原型链继承
b. 借用构造函数
c. 组合继承
d. 混入继承extend
function extend(des,obj){
for(var key in obj){
des[key] = obj[k];
}
}
检测对象类型 instance of
Object.defineProperty(obj, “name”, {
set: function(){
this.name = 'andi'
},
get: function(){
return this.name;
}
})
7. 闭包
一个函数位于另一个函数体内,内部的函数可以访问外部函数的局部变量,这样的内部函数在包含它的外部函数内调用的时候就形成类闭包。
用处:
- 对于一些只执行一次的函数,用匿名自执行函数包起来,这样外部全局环境就用不到它内部的变量,不容易全局污染。
(function(name){ console.log(name) })()
- 结果缓存
- 封装
var person = function(){
var name = 'andi';
return {
getName: function(){
return name;
},
setName: function( newName ){
name = newName ;
}
}
}
这样在访问name时必须通过返回的函数才能访问到。
4. 实现类和继承
8.ES6的新属性,比如promise,对象create等
常量
作用域:块级作用域,大括号内为一个作用域
对象代理
使用new Proxy代理
let person = {name: 'andi',sex: 'male'}
let person = new Proxy(person, {
get(target,key){
return target[key]
},
set(target,key,value){
if(key !== ''sex){
target[key] = value;
}
}
})
默认参数
function name(x,y=10){}
默认参数是一个抛出错误的函数时,就会设置这个参数是必选参数
可变参数(…a)
连接数组不需要concat方法,而是[1,2…arr1]即可
类
箭头函数
和普通函数的区别是this的绑定,ES5是谁调用,this就指向谁,ES6是定义时this指向,不会改变。(构造函数中函数的this指向实例)
()=>{}//参数只有一个的话,小括号可以省略,函数体只有return的话,大括号可以省略
继承
9.伪类和伪元素的区别
伪类是弥补选择器的不足,目的是选择出需要的元素,符号是:first-child,:first-of-type等。而伪元素是虚拟的元素,符号是::before,::after
10.询问项目的问题
11.前端安全
(1)XSS跨站脚本攻击
攻击方式:
反射型:在url里添加可以攻击的代码,发到服务器,之后XSS代码会随响应一起返回给浏览器,导致浏览器执行攻击代码。例如:用iframe加上小广告的页面路径
存储型:提交的代码会存储在服务端,下次请求页面时不用在提交XSS代码。
防范措施:(1)编码,对用户输入的进行ENTITY编码(2)过滤,移除用户上传的DOM属性,SCRIPT或者IFRAME(3)校正
(2)CSRF跨站请求伪造攻击
主要是攻击者使用已登陆的用户cookie去访问该网站做一些危险操作。
防范措施: 1、使用http的post请求来执行所有重要操作;2、在非GET请求中增加伪随机数。
12.前端优化
(1)减少HTTP请求,合并请求,使ajax可缓存
(2)减少操作DOM
(3)少用全局变量
(4)图片懒加载,使用精灵图
(5)压缩js, css
(6)js放在最底部,css放在顶部
(7)
(8)
(9)
13.完整的一次http请求
(1)地址解析,通过DNS域名解析找到主机的IP地址(浏览器自身DNS+操作系统DNS+本地HOSTS+向域名系统发送请求)
(2)建立TCP连接(三次握手)
(3)发起HTTP请求
(4)接收响应结果
(5)浏览器解析HTML(构建DOM树+下载资源+渲染DOM树)
(6)浏览器布局渲染
14.异步加载js的方法
(1)script标签上加上async或者defer属性。async无顺序,defer只在IE中支持
(2)document.write(’
15.编译型语言和解释型语言的区别
两种方式只是翻译的时间不同。
编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了,因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。
解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。解释是一句一句的翻译。Javascript是解释型语言,是直译式脚本语言。
16.常见缓存相关设置
(1)cache-control
(2)Expires
(3)Last-Modified/If-Modified-Since
(4)ETag/If-None-Match
17.https加密
HTTPS就是使用SSL/TLS协议进行加密传输,让客户端拿到服务器的公钥,然后客户端随机生成一个对称加密的秘钥,使用公钥加密,传输给服务端,后续的所有信息都通过该对称秘钥进行加密解密,完成整个HTTPS的流程。
在使用HTTPS是需要保证服务端配置正确了对应的安全证书
客户端发送请求到服务端
服务端返回公钥和证书到客户端
客户端接收后会验证证书的安全性,如果通过则会随机生成一个随机数,用公钥对其加密,发送到服务端
服务端接受到这个加密后的随机数后会用私钥对其解密得到真正的随机数,随后用这个随机数当做私钥对需要发送的数据进行对称加密
客户端在接收到加密后的数据使用私钥(即生成的随机值)对数据进行解密并且解析数据呈现结果给客户
SSL加密建立
18.数组方法
改变原数组的方法: sort(),可接受一个比较函数,reverse() ,splice(),两个参数是删除,三个参数是插入
不改变原数组的方法: concat(),join(),slice()
indexOf(),lastIndexOf(),reduce()
reduce()和 reduceRight()
这两个方法都会实现迭代数组的所有项,然后构建一个最终返回的值。reduce()方法从数组的第一项开始,逐个遍历到最后。而 reduceRight()则从数组的最后一项开始,向前遍历到第一项。
这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。
传给 reduce()和 reduceRight()的函数接收 4 个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。
下面代码用reduce()实现数组求和,数组一开始加了一个初始值10。
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
},10);
console.log(sum); //25
19。清除浮动
列举不同的清除浮动的技巧,并指出它们各自适用的使用场景。
1.使用空标签清除浮动。这种方法是在所有浮动标签后面添加一个空标签定义css clear:both.弊端就是增加了无意义标签。
2.使用overflow。给包含浮动元素的父标签添加css属性overflow:auto;zoom:1;zoom:1用于兼容IE6。
3.使用after伪对象清除浮动。该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置height:0,否则该元素会比实际高出若干像素;二、content属性是必须的,但其值可以为空,content属性的值设为”.”,空亦是可以的。
20.DOM操作方法
document.createElement(eName) //创建一个节点
document.insertBefore(newNode,referenceNode); //在某个节点前插入节点
parentNode.appendChild(newNode); //给某个节点添加子节点
cloneNode(true | false); //复制某个节点 参数:是否复制原节点的所有属性
parentNode.removeChild(node); //删除某个节点的子节点 node是要删除的节点
curtNode.previousSibling; //获取已知节点的相邻的上一个节点
curtNode.nextSlbling; // 获取已知节点的下一个节点
childNode.parentNode; //得到已知节点的父节点
21.手写bind函数
this.value = 2
var foo = {
value: 1
};
var bar = function(name, age, school) {
console.log(name) // 'An'
console.log(age) // 22
console.log(school) // '家里蹲大学'
console.log(this.value) // 1
}
Function.prototype.bind = function(newThis) {
var aArgs = Array.prototype.slice.call(arguments, 1) //拿到除了newThis之外的预置参数序列
var that = this
return function() {
return that.apply(newThis, aArgs.concat(Array.prototype.slice.call(arguments)))
//绑定this同时将调用时传递的序列和预置序列进行合并
}
}
var result = bar.bind(foo, 'An')
result(22, '家里蹲大学')