一、浮动布局(布局简单,兼容性好,可是浮动元素脱离文档流)javascript
二、绝对定位布局(布局快速,元素脱离文档流)css
三、弹性盒子布局(自应性好,兼容性差)html
四、多列布局(宽度自适应)前端
五、table布局(兼容性好)java
好比:header footer nav section article aside dialoggit
<audio controls>
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>
复制代码
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
您的浏览器不支持Video标签。
</video>
复制代码
canvas标签订义图形,好比图表和其余图像,您必须使用脚原本绘制图形web
HTML5 Geolocation API 用于得到用户的地理位置,鉴于该特性可能侵犯用户的隐私,除非用户赞成,不然用户位置信息是不可用的正则表达式
window.navigator.geolocation {
getCurrentPosition: fn 用于获取当前的位置数据
watchPosition: fn 监视用户位置的改变
clearWatch: fn 清除定位监视
} 
复制代码
navigator.geolocation.getCurrentPosition(
function(pos){
console.log('用户定位数据获取成功')
console.log('定位时间:',pos.timestamp)
console.log('经度:',pos.coords.longitude)
console.log('纬度:',pos.coords.latitude)
console.log('海拔:',pos.coords.altitude)
console.log('速度:',pos.coords.speed)
}, //定位成功的回调
function(err){
console.log('用户定位数据获取失败')
} //定位失败的回调
)
复制代码
拖放是一种常见的特性,即抓取对象之后拖到另外一个位置,在 HTML5 中,拖放是标准的一部分,任何元素都可以拖放算法
使用HTML5能够在本地存储用户的浏览数据。早些时候,本地存储使用的是cookies。可是Web 存储须要更加的安全与快速. 这些数据不会被保存在服务器上,可是这些数据只用于用户请求网站数据上.它也能够存储大量的数据,而不影响网站的性能。数据以 键/值 对存在, web网页的数据只容许该网页访问使用。数据库
客户端存储数据的两个对象为:
localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储, 当用户关闭浏览器窗口后,数据会被删除。
无论是 localStorage,仍是 sessionStorage,可以使用的API都相同,经常使用的有以下几个(以localStorage为例):
保存数据:localStorage.setItem(key,value);
读取数据:localStorage.getItem(key);
删除单个数据:localStorage.removeItem(key);
删除全部数据:localStorage.clear();
获得某个索引的key:localStorage.key(index);
WebSocket 是 HTML5 开始提供的一种在单个 TCP 链接上进行全双工通信的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,容许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只须要完成一次握手,二者之间就直接能够建立持久性的链接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只须要作一个握手的动做,而后,浏览器和服务器之间就造成了一条快速通道。二者之间就直接能够数据互相传送
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。 web worker 是运行在后台的 JavaScript,独立于其余脚本,不会影响页面的性能。您能够继续作任何愿意作的事情:点击、选取内容等等,而此时 web worker 在后台运行
dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发,。
darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
drop:事件主体是目标元素,在目标元素彻底接受被拖放元素时触发。
dragend:事件主体是被拖放元素,在整个拖放操做结束时触发
css盒子的四个组成区域相对应,每一个盒子有四个边界:内容边界 Content edge、内边距边界 Padding Edge、边框边界 Border Edge、外边框边界 Margin Edge。
css盒模型分为两种两种标准:一种是标准模型,一种是IE模型
从上图中发现,标准盒模型的宽高就是内容(content)的宽高,而IE盒模型的宽高则是由内容(content)+内边距(padding)+边框(border)的宽高的总和。
事件流描述的是从页面中接受事件的顺序,事件流分为冒泡流和捕获流
###事件冒泡
IE事件流叫作事件冒泡,就是事件开始是由最具体的元素(目标元素)接收,而后逐级向上传播到较为不具体的节点(文档),如图所示
事件捕获是从Document接收到事件,而后逐级向下传播到目标元素,如图所示
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着全部与事件有关的信息,好比事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
下图是事件对象经常使用的属性方法
事件委托是利用事件冒泡,只指定一个事件处理程序来管理某一类型的全部事件。
优势:减小事件注册,节省内存、简化了dom节点更新时,相应事件的更新。 缺点:事件委托基于冒泡,对于不冒泡的事件不支持
http:超文本传输协议,用于从WWW服务器传输超文本到本地浏览器的传输协议。 https:是以安全为目标的HTTP通道,即HTTP下加入SSL层,HTTPS的安全基础是SSL。
区别
客户端在使用HTTPS方式与Web服务器通讯时有如下几个步骤:
http报文由请求报文和响应报文组成
http常见的状态码
//第一种方式:字面量
var o1 = {name: 'o1'};
var o2 = new Object({name: 'o2'});
//第二种方式:经过构造函数
var M = function (name) {
this.name = name;
};
var o3 = new M('o3');
//第三种方式:Object.create
var p = {name: 'p'};
var o4 = Object.create(p);
复制代码
每一个函数被建立的时候都会有一个prototye属性,这个属性会指向函数的原型对象。默认状况下每一个原型对象又都会获取一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针(指向构造函数)
//建立构造函数
function Person (name) {
this.name = name;
}
//在Person函数的原型对象上增长一个方法
Person.prototype.sayName = function (){
console.log(this.name)
}
//Person的原型对象中的constructor属性指向Person函数
Person.prototype.constructor===Person //true
//建立child实例
var child = new Person ('xiaoming');
child.sayName() //xiaoming
复制代码
function Foo1(){
this.name1 = '1';
}
function Foo2(){
this.name2 = '2';
}
Foo2.prototype = new Foo1();
function Foo3(){
this.name3 = '3';
}
Foo3.prototype = new Foo2();
var foo3 = new Foo3();
console.dir(foo3)
console.dir(foo3.name1); //1
3个函数经过__proto__连接起来造成原型链,继承就是经过这个原理来的
复制代码
instanceof 原理:检查左边对象与右边对象是否在同一条原型链上。
constructor原理:取对象的proto属性指向的prototype对象上的constructor字段。
var myNew = function (func) {
var o = Object.create(func.prototype)
var i = func.call(o)
return typeof i === 'object' ? i : o
}
复制代码
js要实现继承,咱们须要一个父类,代码以下:
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
复制代码
核心:将父类的实例做为子类的原型
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name); //cat
console.log(cat.eat('fish')); //cat正在吃:fish
console.log(cat.sleep()); //cat正在睡觉!
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
复制代码
特色:
缺点:
核心:就是子类构造函数内部调用父类构造函数(使用call或者apply方法)
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
复制代码
特色:
缺点:
核心:经过原型链实现对原型属性和方法的继承,经过构造函数来实现对实例属性的继承。
function Cat(name){
Animal.call(this); //第一次调用父类
this.name = name || 'Tom';
}
Cat.prototype = new Animal(); //第二次调用父类
//改变构造函数的指向
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.sleep());//Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
复制代码
特色:
缺点:
核心:经过寄生方式,砍掉父类的实例属性
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 建立一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例做为子类的原型
Cat.prototype = new Super();
})();
// Test Code
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.sleep()); //Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
复制代码
特色:
闭包就是可以读取其余函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的做用域不会被释放
JS中的this不是指向定义他的位置,而是在哪调用它它就指向哪里,箭头函数中的 this 是依赖于所在函数的上下文的,相似于继承的关系。
同源策略限制从一个源加载的文档或脚步如何与来自另外一个源的资源进行交互(协议、域名、端口这3个构成一个源)。这是一个用于隔离潜在恶意文件的关键的安全机制
限制的内容
原理:利用script标签的异步加载来实现的,script标签src属性中的连接能够访问跨域的js脚本,利用这个特性,服务端再也不返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
举个例子:
function test(data){
//打印后端传过来的数据
console.log(data) //data为{a:1,b:2}
}
var url="http://www.x.com/test?callback=test"//向x.com/test告诉他要调用的函数名是“test”
//后台拦截到callback,知道要生成一个调用方法,方法名是test,并传递参数,后台处理生成以下(数据虚构)
test({a:1,b:2})
//而后前端经过script标签去访问并执行,上面的东西
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
//而后就会调用页面的test方法,这就是jsonp的实现原理。
复制代码
把js封装成一个通用组件
function myjsonp(URL,callback,callbackname){
//给系统中建立一个全局变量,叫作callbackname,指向callback函数
//定义
window[callbackname] = callback;
//建立一个script节点
var oscript = document.createElement("script");
//和image不同,设置src并不会发出HTTP请求
oscript.src = URL;
oscript.type = "text/javascript";
//script标签的请求是在上树的时候发出,请求的是一个函数的执行语句
document.head.appendChild(oscript);
//为了避免污染页面,瞬间把script拿掉
document.head.removeChild(oscript);
}
//使用
myjsonp("http://sclub.jd.com/productpage/p-1217508-s-0-t-3-p-1.html?callback=abcdefg",function(data){
console.log(data);
},"abcdefg");
复制代码
原理:原理是利用location.hash来进行传值。
//利用hash,场景是当前页面A经过iframe或frame嵌入了跨域的页面B
//在A中的伪代码以下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'data';
//在B中的伪代码以下:
//onhashchange事件是用来监听当前页面的hash有没有改变
window.onhashchange = function () {
var data = window.location.hash;
}
复制代码
举例来讲,父窗口http://a.com向子窗口http://b.com发消息,调用postMessage方法就能够了
a页面
<iframe id="frame1" src="http://127.0.0.1/JSONP/b.html" frameborder="1"></iframe>
document.getElementById('frame1').onload = function(){
//contentWindow返回的是iframe的window对象,因此后面能够接着调用document方法
var win = document.getElementById('frame1').contentWindow;
win.postMessage("我是来自a页面的","http://127.0.0.1/JSONP/b.html")
}
复制代码
b页面
window.onmessage = function(e){
e = e || event;
console.log(e.data);//我是来自a页面的数据
console.log(e.source);//发送消息的窗口对象
console.log(e.origin);//发送消息窗口的源
}
复制代码
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通讯,同时容许跨域通信,是server push技术的一种很好的实现
整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。
所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯。
参考资料:www.ruanyifeng.com/blog/2016/0…
CSRF,即(Cross-site request forgery), 中文名为跨站请求伪造。是一种挟持用户在当前已登陆的Web应用程序上执行非本意的操做的一种攻击方式。
举个例子:当用户经过身份认证登陆了网站A,这时候网站A的cookie会保存在浏览器中,而后用户又访问了网站B,这时候网站B会有一个引诱点击,这个引诱点击每每是个连接,这个连接指向的就是网站A的API接口,由于浏览器会自动上传cookie,当网站A对身份从新确认发现是合法用户,因此就执行这个接口的动做。
综上所诉:要完成一个CSFR攻击,受害者必须依次完成两个步骤
Token验证:CSRF原理中访问漏洞接口的时候浏览器只上传了cookie,没有手动的上传一个token。这个token是用户登陆注册甚至只是访问网站A,服务器会自动向用户本地存储一个token,在用户访问各个接口的时候,若是没带这个token,服务器就不会经过验证。因此当用户点击引诱连接,这个连接只会自动携带cookie,可是不会自动携带token
Referer验证 (Referer指的是页面来源):服务器经过判断页面来源是否是本身站点的页面来源,若是是就执行接口动做,若是不是一概拦截。
XSS就是跨域脚本攻击
反射型:发出请求时,XSS代码出如今URL中,做为输入提交到服务器端,服务器端解析后响应,XSS代码随响应代码一块儿传给浏览器,最后浏览器解析执行XSS代码。整个过程像一次反射,故叫反射型XSS
储存型:也叫持久型XSS,主要是将XSS代码发送到服务器(无论是数据库、内存仍是文件系统等。),而后在下次请求页面的时候就不用带上XSS代码了
###一、快速排序
原理:
var quickSort = function(arr) {
//若是数组长度小于等于1无需判断直接返回便可
if (arr.length <= 1){ return arr; }
var pivotIndex = Math.floor(arr.length / 2);
//取基准点的值,splice(index,1)函数能够返回数组中被删除的那个数
var pivot = arr.splice(pivotIndex, 1)[0];
console.log(pivot)
var left = [];
var right = [];
for(var i = 0; i < arr.length; i++){
if (arr[i] < pivot){
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
//递归执行以上操做,对左右两个数组进行操做,直到数组长度为<=1;
return quickSort(left).concat([pivot], quickSort(right));
}
复制代码
原理:
1.比较相邻的两个元素,若是前一个比后一个大,则交换位置。
2.第一轮的时候最后一个元素应该是最大的一个。
3.按照步骤一的方法进行相邻两个元素的比较,这个时候因为最后一个元素已是最大的了,因此最后一个元素不用比较
function bSort(arr) {
var len = arr.length;
for (var i = 0; i < len-1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两对比,元素交换,大的元素交换到后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
//举个数组
myArr = [20,18,27,19,35];
//使用函数
bSort(myArr)//[18,19,20,27,35]
复制代码
原理:
function selectSort (arr) {
var len = arr.length;
var temp;
for(var i=0; i<len-1; i++){
for(var j=i+1; j<len; j++){
if(arr[i]>arr[j]){
//互换位置
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
var oldArr = [3,9,4,5,2,8];
selectSort(oldArr); //[2, 3, 4, 5, 8, 9]
复制代码
概念:简单地说就是同一时间只能作一件事,当有多个任务时,只能按照一个顺序一个完成了再执行下一个
任务队列能够分红两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务能够执行了,该任务才会进入主线程执行。
举个例子:
console.log(1) //这个是同步任务,放入主线程里
setTimeout(function(){ //这个是异步任务,放入任务队列中,等同步任务执行完毕,才能执行
console.log(2)
},0)
console.log(3) //这个是同步任务,在主线程里
//运行结果是132
复制代码
主线程从任务队列中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为Event Loop(事件循环)
异步任务的执行顺序准确的划分方式是:
举个例子:
setTimeout(function(){
console.log('定时器开始啦')
});
new Promise(function(resolve){
console.log('立刻执行for循环啦');
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('执行then函数啦')
});
console.log('代码执行结束');
//执行结果是:立刻执行for循环啦 > 代码执行结束 > 执行then函数啦 > 定时器开始啦
//执行原理是:
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里
遇到 new Promise直接执行,打印"立刻执行for循环啦"(Promise函数体里面是同步任务)
遇到then方法,是微任务,将其放到微任务的【队列里】
打印 "代码执行结束"
本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"
到此,本轮的event loop 所有完成。
下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"
复制代码
提高页面性能的方法有哪些?
一、异步加载的方式
二、异步加载的区别
浏览器缓存:“分为强制缓存和协商缓存”,当客户端向浏览器发送请求的时候,若是没有缓存则直接请求服务器。若是有则根据缓存状态来是否从缓存中获取对应的文件
做用:
利用Expires和Cache-Control两个字段来控制
expires:是缓存过时时间(即资源过时时间),是个绝对值。因此若是客户端更改时间,会致使缓存混乱。因此http:1.1增长了cache-control:max-age 字段,它是一个相对的时间
Cache-Control与Expires能够在服务端配置同时启用,同时启用的时候Cache-Control优先级高。
Control:max-age=3600,表明着资源的有效期是3600秒
协商缓存涉及到两组header 字段。
Etag和If-None-Match
Last-Modified和If-Modified-Since
复制代码
Etag和If-None-Match
他们返回的是一个校验码,是个hash值。Etag可以保证资源都是惟一的,是客户端请求服务器的时候服务器返回的。若是资源变化了Etag也会发生变化。当再次请求服务器的时候服务器根据浏览器上送的If-None-Match(以前服务器返回的etag值)值来判断是否命中缓存。
Last-Modified和If-Modified-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。
当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存以前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
若是命中缓存,则返回304,而且不会返回资源内容,而且不会返回Last-Modify。
Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。