前端面试题
面试是很好的成长检验机会
1、windows.onload和$(document).ready()的区别,浏览器加载转圈结束时是那个时间点?
2、form表单当前页面无刷新提交target iframe
3、setTimeout和setInterval区别,如何互相实现?
4、如何避免多重回调--promise,promise简单描述一下,如何在外部进行resolve()
5、margin坍塌?水平方向会不会坍塌?
6、伪类和伪元素区别
7、vue如何实现父子组件通信,以及非父子组件通信
8、数组去重
9、实现两个数组的并集、差集、交集
10、使用flex布局实现三等分,左右两个元素分别贴边,垂直居中
11、如何学习前端的,看了哪些书,关注了哪些公众号?
1、windows.onload和$(document).ready()的区别,浏览器加载转圈结束时是那个时间点?
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个
$(document).ready()可以同时编写多个,并且都可以得到执行
2、form表单当前页面无刷新提交 --> target iframe
<iframe name="formsubmit" style="display:none;"></iframe>
<!-- 将form表单提交的窗口指向隐藏的ifrmae,并通过ifrmae提交数据。 -->
<form action="form.php" method="POST" name="formphp" target="formsubmit">
<div class="form-group">
<label for="uname">用户名:</label>
<input type="text" name="uname" id="uname" />
</div>
<div class="form-group">
<label for="pwd">密 码:</label>
<input type="password" name="pwd" id="pwd" />
</div>
<input type="submit" value="登录" />
</form>
3、setTimeout和setInterval区别,如何互相实现?
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval把它清除。
function interval(func, w, t){
var interv = function(){
if(typeof t === "undefined" || t-- > 0){
setTimeout(interv, w);
try{
func.call(null);
} catch(e){
t = 0;
throw e.toString();
}
}
};
setTimeout(interv, w);
};
4、如何避免多重回调 --> promise,promise简单描述一下,如何在外部进行resolve()
promise可以避免多重回调,promise代表一个异步操作,具有三种状态,Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。只有异步操作才能决定当前是哪一种状态,其他任何操作都改变不了。
promise一旦状态改变,就不会再变,任何时候都可以得到这个结果。
外部进行resolve?
Promise.prototype.then()
5、margin坍塌?水平方向会不会坍塌?
①垂直并列(少见)
垂直之间塌陷的原则是以两盒子最大的外边距为准。
②嵌套关系(常见)
子盒子和父盒子之间并不会出现margin间隙而是父盒子与子盒子一起与页面顶端产生了间隙。
解决方法:
(1)为父盒子设置border,为外层添加border后父子盒子就不是真正意义上的贴合。
(2)为父盒子添加overflow:hidden;
(3)为父盒子设定padding值。
(4)创建BFC处于不同BFC中
水平方向不会出现margin坍塌
6、伪类和伪元素区别
伪类存在的意义是为了通过选择器找到那些不存在于DOM树中的信息以及不能被常规CSS选择器获取到的信息。伪类由一个冒号:开头
伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于文档语言里的。伪元素创建了一个虚拟容器,这个容器不包含任何DOM元素,但是可以包含内容。伪元素的由两个冒号::开头
7、vue如何实现父子组件通信,以及非父子组件通信
组件化的意义(分治复用)
分而治之才是组件化的意义所在,复用只是它的副作用。
组件化是从产品功能角度进行分割,模块化是从代码实现角度进行分割,模块化是组件化的前提和基础。
使用props向子组件传递数据,首先要在子组件中定义子组件能接受的props,然后在父组件中子组件的自定义元素上将数据传递给它:
<template>
<div>
<input type="text" v-model="localMessage" v-on:change="localMessageChange">
</div>
</template>
<script>
export default {
props: ['message'],
data () {
return {
localMessage: this.message
}
}
methods: {
localMessageChange () {
this.$emit('message-change', localMessage) // notify parent component the change of message
}
}
}
</script>
事件系统也能够解决非父子组件的通信问题,我们使用一个空的Vue实例来作为中央事件总线
let Hub = new Vue(); //创建事件中心
<div @click="eve"></div> methods: { eve() { Hub.$emit('change','hehe'); //Hub触发事件 } }
<div></div> created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }
8、数组去重
function unique(array){
var res = [];
var json = {};
for(var i = 0; i < array.length; i++){
if(!json[array[i]]){
res.push(array[i]);
json[array[i]] = 1;
}
}
return res;
}
ES6
function unique(array){
return [...new Set(array)];
}
向Set加入值的时候,不会发生类型转换,所以5和"5"是两个不同的值。其中NaN等于自身,两个对象总是不相等的。
Set的遍历顺序就是插入顺序
Array.from方法可以将 Set 结构转为数组。
去重:
function dedupe(array) {
return Array.from(new Set(array));
}
9、实现两个数组的并集、差集、交集
let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]);
// 并集 let union = new Set([...a, ...b]); // Set {1, 2, 3, 4}
// 交集 let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3}
// 差集 let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
var differenceA = new Set([...a].filter(x => !b.has(x)));
var differenceB = new Set([...b].filter(y => !a.has(y)));
console.log([...differenceA,...differenceB])
//[1,4]
10、使用flex布局实现三等分,左右两个元素分别贴边,垂直居中
<style type="text/css">
body{margin:0;padding: 0;}
.parent{display: flex;color: white;}
.column{flex: 1;}
.column:nth-child(1){background: blue;}
.column:nth-child(2){background: green;}
.column:nth-child(3){background: black;}
</style>
</head>
<body>
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
</div>
</body>
百度二面
1、说下对this的理解
2、实现bind函数
3、数组和链表区别,分别适合的数据结构
4、对mvc的理解
5、http状态码。。。。。401和403区别
6、描述下二分查找
1、说下对this的理解
this 本身原本很简单,总是指向类的当前实例,this 不能赋值。前提是说 this 不能脱离 类/对象 来说,也就是说 this 是面向对象语言里常见的一个关键字。
JS 里的 this(函数的上下文)
在 function 内部被创建
指向调用时所在函数所绑定的对象(拗口)
this 不能被赋值,但可以被 call/apply 改变
this 和构造器
this 本身就是类定义时构造器里需要用到的。this 应该挂属性/字段,方法都应该放在原型上。
function Tab(nav, content) {
this.nav = nav
this.content = content
}
Tab.prototype.getNav = function() {
return this.nav;
};
this 和对象
var tab = {
nav: '',
content: '',
getNav: function() {
return this.nav;
},
setNav: function(n) {
this.nav = n;
}
}
this 和函数
调用方式使用 call/apply
function showMsg() {
alert(this.message)
}
var m1 = {
message: '输入的电话号码不正确'
}
var m2 = {
message: '输入的身份证号不正确'
}
全局环境的 this
this 是 “指向调用时所在函数所绑定的对象”,this 是 “指向调用时所在函数所绑定的对象”,只要函数(function)没有绑定在对象上调用,它的 this 就是 window。
非函数内直接使用 var 声明的变量默认为全局变量,且默认挂在 window 上作为属性。
this 和 DOM/事件
在给元素节点添加事件的时候,其响应函数(handler)执行时的 this 都指向 Element 节点自身。
this 可以被 call/apply 改变
call/apply 是函数调用的另外两种方式,两者的第一个参数都可以改变函数的上下文 this。
ES5 中新增的 bind 和 this
因为是ES5才加的,低版本的IE不支持,可以修复下 Function.prototype.bind。bind 只是 call/apply 的高级版。
ES6 箭头函数(arrow function) 和 this
箭头函数的特征就是,定义在哪,this 就指向那。即箭头函数定义在一个对象里,那箭头函数里的 this 就指向该对象。
2、实现bind函数
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis? this: oThis || window,aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
3、数组和链表区别,分别适合的数据结构
简要概括:
数组静态分配内存,链表动态分配内存;
数组在内存中连续,链表不连续;
数组元素在栈区,链表元素在堆区;
数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
4、对mvc的理解
MVC是Model—View—Controler的简称。即模型—视图—控制器。MVC是一种设计模式,它将业务逻辑、数据、界面显示分离,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
MVC中的模型、视图、控制器它们分别担负着不同的任务。
视图: 视图是用户看到并与之交互的界面。处理界面的显示结果。视图向用户显示相关的数据,并接受用户的输入。视图不进行任何业务逻辑处理。
模型: 模型表示业务数据和业务处理。处理数据,业务逻辑。一个模型能为多个视图提供数据。这提高了应用程序的重用性
控制器: 当用户单击Web页面中的提交按钮时,控制器接受请求并调用相应的模型去处理请求。
然后根据处理的结果调用相应的视图来显示处理的结果。起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。
MVC的处理过程:首先控制器接受用户的请求,调用相应的模型来进行业务处理,并返回数据给控制器。控制器调用相应的视图来显示处理的结果。并通过视图呈现给用户。
5、http状态码。。。。。401和403区别
状态码:
1xx(临时响应)
2xx(成功)
3xx(重定向)
4xx(请求错误)
5xx(服务器错误)
常用的状态码如下:
200 OK //客户端请求成功
302 :请求重定向。
304 :请求资源没有改变,访问本地缓存。
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
410(已删除) //请求的资源已永久删除
500 Internal Server Error //服务器发生不可预期的错误
502(错误网关) //服务器作为网关或代理,从上游服务器收到无效响应。
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
504(网关超时) //服务器作为网关或代理,但是没有及时从上游服务器收到请求。
状态信息:状态信息是根据状态码变化而变化的
6、描述下二分查找
优点是比较次数少,查找速度快,平均性能好;
其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
百度三面
1、为什么选择前端,如何学习的,看了哪些书,博客关注谁?
前端很吸引我,因为它能够快速构建一些东西并分享给别人。把它放在网上,通过一个网址,任何有浏览器的人都可以看到。这就是吸引我开始 Web 开发和 JavaScript 编程的原因。
2、n长的数组放入n+1个数,不能重复,找出那个缺失的数
3、遇到压力最大的一件事,如何解决的
应该算是,研一结束的那个暑假导师才给了我研究的课题,然后调研了一个月后导师临时给我换了个方向,一个基金项目需要一定的论文和专利支撑,那段时间就感觉自己压力很大,通过大量的查阅资料以及和师兄师姐、导师之间的交流沟通,最终确定自己的创新点,并且加班加点实验分析,成功发表了一篇sci论文以及一项发明专利。后来导师又将另一个研究内容交给我去攻坚。
4、做过最有成就感的事是什么?
和队友一起连续两年获得研究生篮球赛团体冠军,同时也实现了电子学院的四连冠,虽然自己在队里不是主力,但也贡献出了自己的一份力量。一群人为了共同的目标一起努力,一起在赛场上拼搏,最终拿下冠军的经历是我永远不会忘记的。虽然只是个小比赛,但在热爱的事情上取得哪怕一点点的成就也会令人很有成就感。
有赞
1、介绍项目,技术难点?
2、图片懒加载怎么做的(getBoundingClientRect)?
3、session的生成规则?sessionid的生成规则?
4、知道哪5种设计模式吗?
5、AMD是什么?解决什么问题?了解AMD,CMD,UMD吗?AMD与CMD的区别?啥叫依赖前置?
6、Object.prototype的原型是什么?
7、对象浅拷贝怎么做?使用JSON.parse(JSON.stringify(...))的方法有什么坏处? 深拷贝?
8、闭包的应用场景是什么?
9、 typeof Funcion答案是什么?
10、事件代理 阻止事件冒泡 阻止事件默认方式
11、详细说说box-sizing属性取值的区别
12、js继承(写了一段)代码,让你实现继承 继承传参问题
13、jQuery的$操作符
14、js中的继承是如何实现的,举例children和parent,怎么实现children继承parent,方式有什么?
15、事件委托是怎么实现的
16、说一下ARP,DNS工作过程,TCP四次挥手中的等待状态。
17、为什么使用IP而不直接使用物理地址。
18、http响应状态码500和501,302和301区别。
1、介绍项目,技术难点?
2、图片懒加载怎么做的?
将img标签src指向一张小图片或者空,定义data-src设置成图片真实地址。当载入页面时,先把可视区域内的img标签的data-src属性值赋给src,然后监听滚动事件,把用户即将看到的图片加载。这样便实现了懒加载。
3、session的生成规则?session id的生成规则?
浏览器第一次访问服务器会在服务器端生成一个session,session在访问tomcat服务器HttpServletRequest的getSession(true)的时候创建
sessionid第一次产生是在直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建。
4、知道哪5种设计模式吗?
模块模式、工厂模式、原型模式、构造器模式、观察者模式、中介者模式、命令模式、外观模式
5、AMD是什么?解决什么问题?了解AMD,CMD,UMD吗?AMD与CMD的区别?啥叫依赖前置?
1. CMD依赖就近:比如如下代码
define(function(require,exports,module){ var a = require('./a'); a.doSomthing(); });
代码在运行时,首先是不知道依赖的,需要遍历所有的require关键字,找出后面的依赖。具体做法是将function toString后,用正则匹配出require关键字后面的依赖。
而AMD依赖前置:如下代码:
define(['./a','./b'],function(a,b){ //...... a.doSomthing(); //...... b.doSomthing(); })
代码在一旦运行到此处,能立即知晓依赖。而无需遍历整个函数体找到它的依赖,因此性能有所提升,缺点就是开发者必须显式得指明依赖——这会使得开发工作量变大,比如:当依赖项有n个时候 那么写起来比较烦 且容易出错。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。
2. 执行顺序上:
CMD是延迟执行的,而AMD是提前执行的。
6、Object.prototype的原型是什么?
null
7、对象浅拷贝怎么做?使用JSON.parse(JSON.stringify(...))的方法有什么坏处? 深拷贝?
浅拷贝:
- function simpleClone(initalObj) {
- var obj = {};
- for ( var i in initalObj) {
- obj[i] = initalObj[i];
- }
- return obj;
- }
深拷贝:
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};
深拷贝2:
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
使用的时候这样写:
var Doctor = deepCopy(Chinese);
8、闭包的应用场景是什么?
闭包通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。
1.使用闭包代替全局变量
2.函数外或在其他函数中访问某一函数内部的参数
3.在函数执行之前为要执行的函数提供具体参数
4.在函数执行之前为函数提供只有在函数执行或引用时才能知道的具体参数
5.为节点循环绑定click事件,在事件函数中使用当次循环的值或节点,而不是最后一次循环的值或节点
6.暂停执行
7.包装相关功能
使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
9、 typeof Funcion答案是什么?
Function
10、事件代理 阻止事件冒泡 阻止事件默认方式
事件代理:delegate
$("#link-list").delegate("a", "click", function(){ // "$(this)" is the node that was clicked console.log("you clicked a link!",$(this)); });
阻止事件冒泡:stopPropagation() cancelBubble = true
阻止事件默认方式:preventDefault () window.event.returnValue = false
11、详细说说box-sizing属性取值的区别
可取值有border-box,content-box,和inherit
border-box:(符合ie盒模型)设置的width、height包括到border,padding变化,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制
content-box:(符合w3c标准盒模型)在宽度和高度之外绘制元素的内边距和边框。
inherit:继承父元素box-sizing属性值
12、js继承代码,让你实现继承 继承传参问题
1.原型链继承
function Parent(){};
function child(){};
child.prototype = new Parent();
child.prototype.constructor = childern;
2.构造函数继承
function Child (name){
Parent.call(this);
this.name = name || 'Tom';
};
3.实例继承
function child(name){
var instance = new Parent();
instance.name = name || 'Tom';
return instance;
}
4.拷贝继承
function child(name){
var parent = new Parent();
for(var p in parent){
child.prototype[p] = parent[p];
}
child.prototype.name = name || 'Tom';
}
5.组合继承
function child(name){
Parent.call(this);
this.name = name || 'Tom';
}
child.prototype = new Parent();
13、jQuery的$操作符
1、选择器
在jQuery中美元符号"$"其实就等同于"jQuery",
2、功能函数前缀
$.trim(sString);
以上代码相当于:
jQuery.trim(sString);
即trim()函数时jQuery对象的一个方法。
3、解决window.onload函数的冲突
由于页面的HMTL框架需要在页面完全加载之后才能使用,因此在DOM编程时window.onload函数频繁被使用。
jQuery中的ready()方法很好的解决了上述问题,它能够自动将其中的函数在页面加载完成后运行,并且同一个页面中可以使用多个ready()方法,而且不互相冲突。
4、创建DOM元素
var oNewP = $("<p>这是一个好故事</p>")
5、自定义添加插件方法"$"
$.fn.disable = function(){
return this.each(function(){
if(typeof this.disabled != "undefined") this.disabled = true;
});
}
解决"$"的冲突
使用jQuery
noConflict() var $j = jQuery.noConflict();
14、js中的继承是如何实现的,举例children和parent,怎么实现children怎么继承parent,方式有什么
通过原型和原型链实现继承
15、事件委托是怎么实现的
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}
事件委托和事件代理什么区别?
事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,利用冒泡的原理,把事件加到父级上,触发执行效果
-------------------------------------------------------------------------
如果我们不想或不能够直接操纵目标对象,我们可以利用delegate创建一个代理对象来调用目标对象的方法,从而达到操纵目标对象的目的。代理对象要拥有目标对象的引用。这就是事件代理(也就是说不会直接去操纵对象)
搜狐
1、用原生js实现复选框选择以及全选非全选功能
2、AMD和CMD区别
1、用原生js实现复选框选择以及全选非全选功能
<script>
window.onload=function(){
var CheckAll=document.getElementById('All');
var UnCheck=document.getElementById('uncheck');
var OtherCheck=document.getElementById('othercheck');
var div=document.getElementById('div');
var CheckBox=div.getElementsByTagName('input');
CheckAll.onclick=function(){
for(i=0;i<CheckBox.length;i++){
CheckBox[i].checked=true;
};
};
UnCheck.onclick=function(){
for(i=0;i<CheckBox.length;i++){
CheckBox[i].checked=false;
};
};
othercheck.onclick=function(){
for(i=0;i<CheckBox.length;i++){
CheckBox[i].checked=!CheckBox[i].checked;
};
};
};
</script>
</head>
<body>
全选:<input type="button" id="All" value="全选" /><br />
全不选<input type="button" id="uncheck" value="全不选" /><br />
反选<input type="button" id="othercheck" value="反选" /><br />
<div id="div">
<input type="checkbox" />ZEALER<br />
<input type="checkbox" />BLOG<br />
<input type="checkbox" />MOOC<br />
</div>
</body>
2、AMD和CMD区别
AMD依赖前置,提前执行;CMD依赖就近,延迟执行。
腾讯
实习
1、移动端性能优化
2、lazyload如何实现
3、点透问题
4、前端安全,csrf、xss原理及如何避免
1、移动端性能优化
2、lazyload如何实现
将页面中的img标签src指向一张小图片或者src为空,然后定义data-src(这个属性可以自定义命名)属性指向真实的图片地址。src指向一张默认的图片,否则当src为空时也会向服务器发送一次请求。可以指向loading的地址。
<img src="default.jpg" data-src="https://www.omvj305k05k3yh.jpg" />
当载入页面时,先把可视区域内的img标签的data-src属性值负给src,然后监听滚动事件,把用户即将看到的图片加载。这样便实现了懒加载。
3、点透问题
为什么会出现点透(A遮罩层,B底层)
click延迟,延迟,还是延迟。
在移动端不使用click而用touch事件代替触摸是因为click事件有着明显的延迟,具体touchstart与click的区别如下:
1.touchstart:在这个DOM(或冒泡到这个DOM)上手指触摸开始即能立即触发 2.click:在这个DOM(或冒泡到这个DOM)上手指触摸开始,且手指未曾在屏幕上移动(某些浏览器允许移动一个非常小的位移值),且在这个在这个dom上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短(某些浏览器不检测间隔时间,也会触发click)才能触发
也就是说,事件的触发时间按由早到晚排列为:touchstart 早于 touchend 早于 click。亦即click的触发是有延迟的,这个时间大概在300ms左右。
由于我们在touchstart阶段就已经隐藏了罩层A,当click被触发时候,能够被点击的元素则是其下的B元素,根据click事件的触发规则:
只有在被触发时,当前有click事件的元素显示,且在面朝用户的最前端时,才触发click事件。
由于B绑定了click事件(或者B本身默认存在click事件),所以B的click事件被触发,产生了点透的情况。
解决方案
1.对于B元素本身没有默认click事件的情况(无a标签等),关于触摸事件应统一使用touch事件。
2.对于B元素本身存在默认click事件的情况,应及时取消A元素的默认点击事件,从而阻止click事件的产生。即代码如下:
if(eve == "touchend") e.preventDefault();
3.对于遮盖浮层,由于遮盖浮层的点击即使有小延迟也是没有关系的,反而会有疑似更好的用户体验,所以这种情况,可以针对遮盖浮层自己采用click事件,这样就不会出现点透问题。
4、前端安全,csrf、xss原理及如何避免
1、XSS攻击(XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。)
浏览器遇到html中的script标签的时候,会解析并执行标签中的js脚本代码,那么如果你的用户名称里面含有script标签的话,就可以执行其中的代码了。
img标签,在加载图片失败的时候,会调用该元素上的onerror事件。我们正可以利用这种方式来进行攻击。
如何防范
浏览器遇到script标签的话,则会执行其中的脚本。但是如果我们将script标签的进行转义,则浏览器便不会认为其是一个标签,但是显示的时候,还是会按照正常的方式去显示。将前端输出数据都进行转义。
2、CSRF攻击(跨站请求伪造)
其实就是网站中的一些提交行为,被黑客利用,你在访问黑客的网站的时候,进行的操作,会被操作到其他网站上
合理使用post与get
3、网络劫持攻击
4、控制台注入代码
5、钓鱼
我们平时开发要注意些什么?
- 开发时要提防用户产生的内容,要对用户输入的信息进行层层检测
- 要注意对用户的输出内容进行过滤(进行转义等)
- 重要的内容记得要加密传输(无论是利用https也好,自己加密也好)
- get请求与post请求,要严格遵守规范,不要混用,不要将一些危险的提交使用jsonp完成。
- 对于URL上携带的信息,要谨慎使用。
- 心中时刻记着,自己的网站哪里可能有危险。
校招
1、原生js模板引擎
2、移动端性能优化
3、repaint和reflow区别
4、requirejs如何避免循环依赖
5、盒子模型
6、实现布局:左边一张图,右边一段文字(不是环绕)
1、原生js模板引擎
2、移动端性能优化
3、repaint和reflow区别
repaint是某个dom元素进行重绘,reflow是整个页面进行重排,也就是对页面所有的dom元素渲染。
http://blog.csdn.net/lululul123/article/details/54143224
4、requirejs如何避免循环依赖
5、盒子模型
标准 w3c 盒子模型的范围包括 margin、border、padding、content,并且 content 部分不包含其他部分。
ie 盒子模型的范围也包括 margin、border、padding、content,和标准 w3c 盒子模型不同的是:ie 盒子模型的 content 部分包含了 border 和 pading。
offsetWidth=(width+padding+border)
clientWidth=(width+padding)
6、实现布局:左边一张图,右边一段文字(不是环绕)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定宽与自适应</title>
<style type="text/css">
*{margin: 0 auto;}
.parent{display: flex;}
.left{margin-right: 10px;}
.right{flex:1;background-color: blue;} //left内容自适应,
</style>
</head>
<body>
<div class="parent">
<div class="left">
<img src="" alt="">
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
</body>
</html>
猿辅导
1、为什么选择前端?
2、移动端性能优化?
3、vue的特点?双向数据绑定是如何实现的?
4、算法题—数组去重,去除重复两次以上的元素
5、代码题—嵌套的ul-li结构,根据input输入的内容,去除相应的li节点,且如果某个ul下的li都被移除,则该ul的父li节点也要被移除
6、页面加载过程?
7、浏览器如何实现图片缓存?
2、移动端性能优化?
pc常用的优化手段:(大部分适用于移动端)
代码优化(css、html、js优化)
减少HTTP请求(雪碧图,文件合并…)
减少DOM节点
无阻塞(内联CSS,JS置后…)
缓存
移动端性能优化:
加载:
1.预加载
1.显性加载
2.隐性加载
2.按需加载
1.在首屏加载的时候把首屏的内容加载尽量,而位于首屏之外的元素都只在出现在首屏才加载,很大程度地节省了流量,提升了首次加载时间。
2.响应式加载方式,意思是利用js或者css判断分辨率,从而选择不同尺寸的图片进行引入,这种的好处显而易见,同样可以加快加载速度和节省流量。
3.压缩图片
对于移动端的Jpg文件,有这样的结论:
a.使用大尺寸大有损压缩比的jpg
b.使用jpegtran进行无损压缩
而对于png有以下结论:
a.多彩图片使用png24
b.低彩图片使用png8
c.推荐使用pngquant
4.尽量避免重定向
因为它重复了域名查找,tcp链接,发送请求。
5. 使用其他方式代替图片
第一种是:依靠css3绘制图片
第二种:使用iconfont代替小尺寸图片
脚本执行:
1.尽量避免DataURI
经测试,DataURI要比简单的外链资源慢6倍,生成的代码文件相对图片文件体积没有减少反而增大,而且浏览器在对这种base64解码过程中需要消耗内存和cpu,这个在移动端坏处特别明显。
2.点击事件优化
在移动端请适当使用touchstart,touchend,touch等事件代替延迟比较大的click事件。Click之所以慢是因为mousedown导致的
渲染:
1. 动画优化
a) 尽量使用css3动画
优点:不占用js主线程、可利用硬件加速、浏览器可对动画做优化
缺点:不支持中间状态监听
b) 适当使用canvas动画
优点:可规避渲染树的计算渲染更快
缺点:开发成本高、维护较麻烦
得到结论:5个元素以内使用css3动画,5个以上使用canvas动画。
c) 合理使用RAF(requestAnimationFrame)
优点:能解决脚本问题引起的丢帧,卡顿问题
支持中间状态监听
缺点:兼容问题
2. 高频事件优化
类似touchmove,scroll这类的事件可导致多次渲染,对于这种事件可以通过以下手段进行优化
1.使用requestAnimationFrame监听帧变化,使得在正确的时间进行渲染
2.增加响应变化的时间间隔,减少重绘次数。
绘制/合成:
GPU加速
触发GPU加速的方式有:
CSS3 transitions、 CSS3 3D transforms、 WebGL 3D 绘制、 Video ...
其实优化是双刃剑
按需加载提升速度,但可能导致大量重绘;
Touch响应快,但很多场景不适合;
GPU加速效率高,但内存开销大等等
Loading会让整体体验流畅,但容易造成用户流失
图片压缩让带宽成本降低,但可能会导致视觉效果变差
3、vue的特点?双向数据绑定是如何实现的?
1.轻量级的框架
2.双向数据绑定
3.指令
4.插件化
AngularJS 采用“脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现。如果是手动对 ViewModel 的数据进行变更,为确保变更同步到视图,需要手动触发一次“脏值检测”。
VueJS 则使用 ES5 提供的 Object.defineProperty() 方法,监控对数据的操作,从而可以自动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。
4、数组去重
function unique(array){
var res = [];
var json = {};
for(var i = 0; i < array.length; i++){
if(!json[array[i]]){
res.push(array[i]);
json[array[i]] = 1;
}
}
return res;
}
var array = [1,1,1,1,1];
unique(array);
6、页面加载过程(从url输入到网页渲染的过程)?
1、检查缓存是否存在
2、解析url获取host,并将主机名转化成服务器ip地址
3、解析出端口号
4、浏览器与服务器建立tcp连接(三次握手)
5、浏览器向服务器发送HTTP请求
6、服务器处理请求并返回响应
7、浏览器检查返回响应状态码是否为3xx重定向、4xx、5xx错误等,具体情况分类处理
8、浏览器接收http响应
9、浏览器解码响,若能存入缓存则存入
10、浏览器显示html页面
11、浏览器发送请求获取嵌入html的资源
12、浏览器发送异步请求
13、页面渲染完成
7、浏览器如何实现图片缓存?(HTTP缓存机制及原理)
报文信息主要分为两部分
1.包含属性的首部(header)--------------------------附加信息(cookie,缓存信息等)与缓存相关的规则信息,均包含在header中
2.包含数据的主体部分(body)-----------------------HTTP请求真正想要传输的部分
HTTP缓存有多种规则,根据是否需要重新向服务器发起请求来分类,我将其分为两大类(强制缓存,对比缓存)
对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
对于比较缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
浏览器第一次请求:
浏览器再次请求时:
网易一面
1. CSS3布局、动画;
2. 事件如何在冒泡阶段被某个元素捕获(target属性)
3. DOM元素的移动
4.对新技术的了解
5.queryselector
6.js的Array相关
1. CSS3布局、动画
transition和animation
Transition(过渡)这个概念之前,CSS是没有时间轴的。
transition的作用在于,指定状态变化所需要的时间。
img{ transition: 1s 1s height ease; }
CSS Animation需要指定动画一个周期持续的时间,以及动画效果的名称。
要用keyframes关键字,定义动画帧效果。
2. 事件如何在冒泡阶段被某个元素捕获(target属性)
(1)捕获阶段(Capture Phase)
事件的第一个阶段是捕获阶段。事件从文档的根节点流向目标对象节点。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。
(2)目标阶段(Target Phase)
当事件到达目标节点的,事件就进入了目标阶段。事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的文档节点。
(3)冒泡阶段(Bubble Phase)
事件在目标元素上触发后,并不在这个元素上终止。它会随着DOM树一层层向上冒泡,回溯到根节点。
冒泡过程非常有用。它将我们从对特定元素的事件监听中释放出来,如果没有事件冒泡,我们需要监听很多不同的元素来确保捕获到想要的事件。
3. DOM元素的移动
js 添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
将页面上的一个节点移动到另外一个地方可以用jquery的内部和外部插入方法(append,appendTo,prepend,prependTo,after,before,insertAfter,insertBefore),直接将选中的节点传递进去就可以实现移动
4.对新技术的了解
ES6
5.querySelector()、querySelectorAll()
querySelector和querySelectorAll的参数须是符合 css selector 的字符串。
不同的是querySelector返回的是一个对象,querySelectorAll返回的一个集合(NodeList)。
使用这两个方法无法查找带伪类状态的元素,比如querySelector(':hover')不会得到预期结果,可以进行转义,需要两个反斜杠querySelector('.foo\\:hover'),一次是字符串当中,一次是querySelector解析参数时。
document.querySelector("h2, h3")-->选择DOM结构中第一个出现的h2或h3
querySelectorAll()该方法返回所有满足条件的元素,结果是个nodeList集合。
但需要注意的是返回的nodeList集合中的元素是非实时(no-live)的,想要区别什么是实时非实时的返回结果,请看下例:
<div id="container"> <div></div> <div></div> </div> //首先选取页面中id为container的元素 container=document.getElementById('#container'); console.log(container.childNodes.length)//结果为2 //然后通过代码为其添加一个子元素 container.appendChild(document.createElement('div')); //这个元素不但添加到页面了,这里的变量container也自动更新了 console.log(container.childNodes.length)//结果为3
6.js的Array相关
改变自身的方法
sort()、push()、pop()、shift()、unshift()、splice()、reverse()、fill()
改变自身的方法
concat()、includes()、join()、slice()、toString()、indexOf()、lastIndexOf()
遍历方法
forEach()、every()、some()、filter()、find()、map()、reduce()
网易二面
1.1 哪些块级元素,行内元素
1.2 垂直居中布局(元素文字行数不确定)
1.3 js类型隐式转换
1.4 对象深拷贝(不考虑继承属性)
1.5 10~100随机数取10个到数组中从小到大排序
1.6 可继承的属性
1.1 哪些块级元素,行内元素
块级元素:div ul ol li p h1 h2 h3 h4 dl table form
行内元素:a span strong input img select
1.2 垂直居中布局(元素文字行数不确定)
<style type="text/css">
.parent{ position: relative; height: 500px;}
.child{ position: absolute;top:50%;transform: translateY(-50%); }
</style>
</head>
<body>
<div class="parent">
<div class="child">demo</div>
</div>
</body>
1.3 js类型隐式转换
一.值类型之间的数据类型转换:
(1)数字和字符串使用+运算符:
JavaScript会自动把数字转换成字符的,不管数字在前还是字符串在前.
(2)布尔值参与的+运算符操作:
首先会将布尔值转换为对应的数字或者字符串,然后再进行相应的字符串连接或者算数运算。
(3)减法操作:
如果进行减法操作,那么两个操作数都会先被转换为数字,然后在进行算数运算。
(4)==等性运算:
undefined和null比较特殊,它们两个使用==运算符返回值是true。
其他值类型进行比较的时候都会将运算数转换为数字
二.引用类型转值类型:
调用toString()或者valueOf()将对象转换成字符串或者数字的规则如下:
调用toString()时,如果对象具有这个方法,则调用此方法;如果此方法返回一个值类型数据,
那么就返回这个值类型数据,然后再根据所处的上下文环境进行相关数据类型转换。如果没有
toString(),或者此方法返回值并不是一个值类型数据,那么就会调用valueOf()(如果此方法存
在的话),如果valueOf()返回一个值类型数据,那么再根据所处的上下文环境进行相关的数据
类型转换。
总结如下:
大多数对象隐式转换为值类型都是首先尝试调用valueOf()方法。但是Date对象是个例外,此对
象的valueOf()和toString()方法都经过精心重写,默认是调用toString()方法,比如使用+运算符,
如果在其他算数运算环境中,则会转而调用valueOf()方法。
1.4 对象深拷贝(不考虑继承属性)
浅拷贝:
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
深拷贝:
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object'?cloneObj(obj[i]):obj[i];
}
}
return newobj;
};
深拷贝2:
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
使用的时候这样写:
var Doctor = deepCopy(Chinese);
1.5 10~100随机数取10个到数组中从小到大排序
function tensort(len){
var arr = new Array(len);
for(var i=0;i<len;i++){
arr[i]=Math.floor((Math.random()*91))+10;
}
arr.sort(function(a,b){return a-b;});
}
tensort(10);
1.6
可继承的属性:font-size font-family color letter-spacing word-spacing white-space line-height
不可继承的属性:border magin padding height width display background position overflow