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 这种方式对我来说不太便于理解

<div class="wp">
    <div class="wp-inner">
        <div class="box">123123</div>
    </div>
</div>

/* 定位代码 */
.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单元格的内容本身就是垂直居中的 所以加一个水平居中即可

<table>
    <tbody>
        <tr>
            <td class="wp">
                <div class="box">123123</div>
            </td>
        </tr>
    </tbody>
</table>
.wp {
    text-align: center;
}
.box {
    display: inline-block;
}

(5) css-table table-cell

<div class="wp">
    <div class="box">123123</div>
</div>
.wp {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
.box {
    display: inline-block;
}

(6) flex

<div class="wp">
    <div class="box">123123</div>
</div>
.wp {
    display: flex;
    justify-content: center;
    align-items: center;
}

(7) css 网格布局grid

<div class="wp">
    <div class="box">123123</div>
</div>
.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.onload=function () {
  console.log(xdr.responseText);
}
xdr.onerror=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.onload=img.onerror=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<script>标签的onerror事件处理程序还没有得到支持,为此不得不使用计时器查看指定时间内是否接收到了响应,但并非完美的解决方式。

(3) Comet

Ajax是一种页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。

实现方式:长轮询和流。

长轮询:浏览器发送请求,服务器接收到后保持连接打开,直到有数据可以发送,发送完数据后又关闭连接。

与短轮询的区别:都需要浏览器先发起对服务器的连接。但服务器如何发送数据是其中区别,短轮询是服务器立即发送响应,无论数据是否有效,长轮询是等待发送响应。

轮询优势:所有浏览器都支持,使用XHR对象和setTimeout()即可实现。

HTTP流:浏览器向服务器发送一个请求,服务器保持连接打开,周期性地向浏览器发送数据。比如sleep(10)

在Firefox、Safari、Opera和Chrome中,通过侦听readystatechange事件以及检测readyState的值是否为3,就可以通过XHR对象实现HTTP流。readystate值为3则根据received属性值对responseText进行分割以取得最新数据。通过progress回调函数处理传入的新数据。当readyState值为4时,执行finished回调函数,传入响应返回的全部内容。

(4) Web Sockets

浏览器API,目标是在一个单独的持久连接上提供全双工、双向通信。要使用支持这种协议的服务器,才能正常工作。

未加密连接http->ws,加密连接https->wss

好处:能够在客户端和服务器之间发送非常少量的数据而不必担心HTTP那样字节级的开销,由于传递的数据包很小,因此web sockets很适合移动应用。

缺点:对于这种自定义协议而言,制定协议的时间比制定JavaScript API的时间还要长。

使用方式:

var socket=new WebSocket("ws://www.example.com/server.php");//必须是绝对URL
socket.send("Hello World");

对于复杂的数据结构而非文本来说,要先序列化为一个JSON字符串再发送到服务器。

var message={
  time: new Date(),
  text: "Hello World",
  clientId: "asdftrj6fk"
};
socket.send(JSON.stringify(message));
//接收到服务器端发来的数据就会触发message事件
socket.onmessage=function(event){
  var data=event.data;
  //处理data字符串
}

为确保通过XHR访问的URL安全,常用做法就是验证发送者是否有权限访问相应的资源。有以下几种方式。

1. 要求以SSL连接来访问可以通过XHR请求的资源。(

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。)

2. 要求每一次请求附带经过相应算法计算得到的验证码。

注意以下方式对CSRF攻击防范不起作用:

要求发送POST请求而不是GET请求-很容易改变

检查来源URL以确定是否可信-来源记录容易伪造

基于Cookie信息进行验证-也很容易伪造


vue 组件通信 vuex

笔试背包问题 数组去重

最近看的技术博客是哪篇?

总体问题不多 会考察逻辑 最后介绍自己优缺点 也是面试官比较看重的

以及 简历要准备多份

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值