0612vivo提前批一面

岗位:软件工程师(前端)


  1. CSS选择器以及优先级 子绝父相定位 水平垂直居中

CSS选择器有

  • 标签选择器、类名选择器、多类名选择器、ID选择器、通配符选择器(*)
  • 伪类选择器(链接伪类选择器,lvha,:link 未访问 :visited已访问 :hover鼠标移上去 :active被鼠标选定瞬间的状态;结构伪类选择器,:nth-child(数字、关键词even/odd、公式2n+1)、nth-last-child、first-child、last-child;目标伪类选择器 :target 选择当前处于活动状态的元素)、伪元素选择器(:before、:after在元素开始或结束位置插入新行内元素,必须结合content属性)
  • 复合选择器(交集选择器 比如h3.cls、并集选择器 逗号隔开、后代选择器 空格隔开、子元素选择器 >隔开)
  • 属性选择器(选取带有特殊属性的标签 比如a[title]表示带有title属性的a标签 div[class^=font]表示类名以font开头的div)

水平垂直居中 参考前端之巅的这篇文章https://mp.weixin.qq.com/s/uTnMr4lv_Hrlt2TH9A01gA 一共10种方式可参考

  • 居中元素定宽高 假设宽高都是100px

(1) absolute+负margin 

/* 定位代码 */
.wp {
    position: relative;
}
.box {
    position: absolute;;
    top: 50%;
    left: 50%;
    margin-left: -50px;
    margin-top: -50px;
}

(2) absolute+margin auto

.wp {
    position: relative;
}
.box {
    position: absolute;;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}

(3) absolute+css3计算属性 cal

.wp {
    position: relative;
}
.box {
    position: absolute;;
    top: calc(50% - 50px);
    left: calc(50% - 50px);
}
  • 居中元素不定宽高

(1) absolute+transform 因为transform是针对自身的宽高比例 所以不必指定宽高

.wp {
    position: relative;
}
.box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

(2) line-height+text-align+vertical-align  initial表示默认值 这里不用initial就会变成父元素的高度 否则是行内元素包裹内容的高度

/* 定位代码 */
.wp {
    line-height: 300px;
    text-align: center;
    font-size: 0px;
}
.box {
    font-size: 16px;
    display: inline-block;
    vertical-align: middle;
    line-height: initial;
    text-align: left; /* 修正文字 */
}

(3) writing-mode 可以改变文字的显示方向 文字水平变垂直 水平属性变垂直属性 比如text-align 这种方式对我来说不太便于理解

123123
/* 定位代码 */ .wp { writing-mode: vertical-lr; text-align: center; } .wp-inner { writing-mode: horizontal-tb; display: inline-block; text-align: center; width: 100%; } .box { display: inline-block; margin: auto; text-align: left; }

(4) table 因为table单元格的内容本身就是垂直居中的 所以加一个水平居中即可

123123
.wp { text-align: center; } .box { display: inline-block; }

(5) css-table table-cell

123123
.wp { display: table-cell; text-align: center; vertical-align: middle; } .box { display: inline-block; }

(6) flex

123123
.wp { display: flex; justify-content: center; align-items: center; }

(7) css 网格布局grid

123123
.wp { display: grid; } .box { align-self: center; justify-self: center; }

总结:

PC端有兼容性要求,宽高固定,推荐absolute+负margin

PC端有兼容性要求,宽高不固定,推荐css-table

PC端无兼容性要求,推荐flex

移动端推荐使用flex


2. JS 原型链 继承

JS继承

  • 原型链:让原型对象等于另一个类型的实例 SubType.prototype=new SuperType()

(1)所有函数的默认原型都是Object的实例,因此默认原型内都会包含一个内部指针,指向Object.prototype。

(2)如何确定实例和原型的关系呢?两种方式:instanceof()和isPrototypeOf(),只要原型链中出现过,就会返回true。所以:

instance instanceof Object与Object.prototype.isPrototypeOf(instance)都会返回true

(3)定义方法需要注意两项:

必须在用SuperType的实例替换原型之后,再添加新方法或者重写父类型中的方法。

不能用字面量方式添加新方法,否则会使原型继承失效。因为这种方式是替换而不是添加。此时原型链已经被切断。

SubType.prototype=new SuperType();
SubType.prototype={
  getSubValue: function () {
    return this.subproperty; 
  },
  someOtherMethod: function () {
    return false;
  }
}
var instance=new SubType();
console.log(instance.getSuperValue());//error!

(4) 原型链存在的问题:

所有子类型的实例都共享这一个colors属性,一处修改全部改变。

function SuperType(){
  this.colors=["red","blue"];
}
function SubType(){
}
SubType.prototype=new SuperType();
var instance1=new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//red,blue,black

var instance2=new SubType();
console.log(instance2.colors);//red,blue,black

在创建子类型的实例时,不能向父类型的构造函数中传递参数。

  • 借用构造函数

解决了原型链共用引用类型值的问题。在子类型构造函数的内部调用父类型构造函数。

function SuperType(){
  this.colors=["red","blue"];
}
function SubType(){
  SuperType.call(this);
}
var instance1=new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//red,blue,black

var instance2=new SubType();
console.log(instance2.colors);//red,blue 因为每次都会重新构造一遍

解决了原型链继承不能向父类型传值的问题。

function SuperType(name){
  this.name=name;
}
function SubType(){
  SuperType.call(this,"Nicolas");//传值
  this.age=29;//新增加的属性
}
var instance1=new SubType();
console.log(instance1.name);//"Nicolas"
console.log(instance1.age);//29

这种方式的主要问题就是父类型的原型中定义的方法对于子类型而言是不可见的。

  • 组合继承(原型链+借用构造函数)

原型链-原型属性方法的继承,借用构造函数-实例属性的继承

function SuperType(name){
  this.name=name;
  this.colors=["red","blue"];
}
SuperType.prototype.sayName=function(){
  console.log(this.name);
};
function SubType(name,age){
  SuperType.call(this,name);
  this.age=age;//子类型的新属性
}

SubType.prototype=new SuperType();
SubType.prototype.constructor=SubType;//手动指定构造函数

SubType.prototype.sayAge=function(){
  console.log(this.age);
}
var instance1=new SubType("zs",20);
instance1.colors.push("black");
console.log(instance1.colors);//red,blue,black
instance1.sayName();//"zs"
instance1.sayAge();//20

var instance2=new SubType("ls",23);
console.log(instance2.colors);//red,blue
instance2.sayName();//"ls"
instance2.sayAge();//23
  • 原型式继承

在没必要兴师动众地创建构造函数,而只想让一个对象与另一个对象保持类似的情况下,可以采用原型式继承。但是,包含引用类型值的属性值会被实例所共享,就像原型模式一样。

function object(o){
  function F(){
    F.prototype=o;
    return new F();
  }
}
//相当于创建了o的两个副本

ECMAScript5的Object.create()方法规范化了原型式继承。在传入一个参数的情况下和object()方法一样,两个参数的情况下指定的任何属性都会覆盖原型对象上的同名属性。

var person={
  name: "Nicolas",
  friends: ["zs","ls"]
};
//每个属性都是通过自己的描述符定义的
var anotherPerson=Object.create(person,{
  name: {
    value: "ljs"
  }
});
console.log(anotherPerson.name);//"ljs"
  • 寄生式继承 不一定要采用object方法,返回新对象的函数都适用这个模式。
function createAnother(o){
  var clone=object(o);
  clone.sayHi=function(){//在已有对象的基础上添加新成员
    console.log("hi");
  }
  return clone;
}
  • 寄生组合式继承

解决了组合继承方式调用两次父类构造函数的问题。本质上,使用寄生式方法继承父类型的原型,再将结果指定给子类型的原型,相当于一个副本。

function inheritPrototype(subType,superType){
  var protoType=object(superType.prototype);//创建副本
  prototype.constructor=subType;//指定构造函数
  subType.prototype=prototype;//指定原型
}

3. 跨域

同源策略:相同域、相同协议、相同端口

通过XHR实现Ajax通信的一个主要限制,来源于跨源安全策略。默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。解决方案简称CORS(Cross-Origin Resource Sharing,跨域源资源共享),是W3C的一个工作草案,定义了在必须访问跨域资源时,浏览器与服务器的沟通方式。

基本思想:使用自定义的HTTP头部让浏览器与服务器进行沟通,从而确定请求或响应是成功还是失败。

实现方式:

(1) IE-XDR

与XHR类似,不同之处在于以下几点:

Cookie不会随请求发送/随响应返回

只能设置请求头部信息中的Content-Type字段

不能访问响应头部信息

只支持GET和POST请求

注意:

这些变化使得CSRF(Cross-Site Request Forgery,跨站点请求伪造)和XSS(Cross-Site Scripting,跨站点脚本)问题得到了缓解。

作为请求的一部分,Origin头部的值表示请求的来源域,以便远程资源明确的识别XDR请求。

XDR也是先创建实例,再调用open()和send()方法,但open()方法只接受两个参数:请求的类型和URL

为了支持POST请求,XDR对象提供了contentType属性,用来表示发送数据的格式。

xdr.contentType="application/x-www-form-urlencoded";

所有XDR请求都是异步执行的。请求返回后会触发load事件,接收到请求后只能访问响应的原始文本responseText

为了检测错误,可以指定一个onerror事件处理程序

var xdr=new XDomainRequest();
xdr.οnlοad=function () {
  console.log(xdr.responseText);
}
xdr.οnerrοr=function (){
  console.log("An error occured");
}
xdr.open("get","http://www.somewhere-else.com/page/");
xdr.send(null);

(2) 其他浏览器-XHR

其他浏览器通过XMLHttpRequest对象实现了对CORS的原生支持。要请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可。本地资源最好使用相对URL。

xhr.open("get","http://www.somewhere-else.com/page/",true);

与IE中XDR对象不同,通过跨域XHR对象可以访问status和statusText属性,而且支持同步请求。但也存在一些限制:

不能使用setRequestHeader()设置自定义头部

不能发送和接收cookie

调用getAllResponseHeaders()方法总会返回空字符串。

(3) Preflighted Requests支持开发人员使用自定义头部。

浏览器:

Origin,Access-Control-Request-Method:请求自身使用的方法,Access-Control-Request-Headers:(可选)自定义的头部,多个头部用逗号分隔。

服务器:

Access-Control-Allow-Origin,Access-Control-Allow-Methods(多个方法用逗号分隔),Access-Control-Allow-Headers(多个头部用逗号分隔),Access-Control-Max-Age:应该将这个Preflight请求缓存多少时间。

(4) 带凭据的请求

默认情况下跨域请求不提供凭据(cookie、HTTP认证及客户端SSL证明等),通过将withCredentials属性设置为true可以指定某个请求应该发送凭据。服务器接收到后会用以下HTTP头部来响应:

Access-Control-Allow-Credentials:true

如果发送的是带凭据的请求但服务器响应没有包含这个头部,那么浏览器就不会把响应交给JavaScript,responseText为空字符串,status为0,调用onerror()处理程序。

(5) 跨浏览器的CORS

检测XHR是否支持CORS的最简单方式就是检测是否存在withCredientials属性,再结合检测XDomainRequest对象是否存在,就可以兼顾所有浏览器了。

总结:

XDR和XHR对象的共同属性/方法:

abort()-停止正在进行的请求

onerror()-替代onreadystatechange检测错误

onload()-替代onreadystatechange检测成功

responseText用于取得响应内容

send()用于发送请求

其他跨域技术:不依赖XHR对象的方式

(1) 图像Ping

一个网页可以从任何网页中加载图像,不必担心跨域与否。通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,能知道响应是什么时候收到的。

var img=new Image();
img.οnlοad=img.οnerrοr=function(){
  console.log("Done");
}
img.src="http://www.example.com/test?name=Nico"

请求从设置src属性那一刻开始。

图像Ping最常用于跟踪用户点击页面或动态广告曝光次数。图像Ping有两个主要的缺点,一个是只能发送GET请求,二是无法访问服务器的响应文本。用于单向通信。

(2) JSONP

JSONP是通过动态sript标签来使用的,使用时可以为src属性指定一个跨域URL。JSONP由两部分组成:回调函数和数据。回调函数是当响应到来是应该在页面中调用的函数,名字一般在请求中指定。数据就是传入回调函数中的JSON数据。

function handleResponse(response){
  console.log("You're at IP "+response.ip+",which id in"+response.city+","+response.region_name);
}
var script=document.createElement("script");
script.src="http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);

通过查询地理定位服务显示IP和位置信息。

JSONP的不足:如果其他域不安全,很可能在响应中包含一些恶意代码。其次,要确定JSONP请求是否失败并不容易,H5

你可能感兴趣的:(面经)