现在自己的 github 下新建一个叫做 blog 的仓库。然后到本地找个目录:
|
|
|
|
|
|
|
|
给博客安装 5 个插件:
写在 package.json
文件中,通过 npm install
即可安装。
|
|
├── _config.yml # 配置文件
├── package.json # npm 配置文件
├── public # 别鸟他
├── scaffolds # 别鸟他
├── source # 文章全部在这里
│ ├── CNAME # 用于配置域名
│ ├── _posts # 文章内容(文件夹)
│ └── about # 可直接访问的页面
└── themes # 主题,可在 _config.yml 中配置主题类型
├── jacman
└── landscape
配置 _config.yml,在最后找到:
|
|
将 repository 改成你自己的地址,https://github.com/zhangmengxue/blog.git
目前在 master 分支下操作,执行下面的命令之后,会在 github 上自动生成一个 gh-pages 分支,这个分支不用理会,它是自动生成的。只需要在这个分支下开发。
|
|
编辑的文档使用的 md 语法,使用 hexo g
将 md 文件编译成 html 文件,然后执行 hexo s
就可以在本地预览了。
更多信息: Generating
|
|
会开启一个端口为 4000 的本地服务器,可以用于本地调试
更多信息: Server
|
|
更多信息: Deployment
|
|
|
|
这句命令会在 source/_posts 下生成一个叫做 post-name.md 的文件,然后通过 hexo d -g
,打开本地服务器查看网页内容。
|
|
这条命令就可以生成一个 about 页面。
更多信息: Writing
|
|
在 themes/jacman 中可以配置页面信息,css 采用 stylus 写的,博客信息的配置也可在 themes/jacman/_config.yml
中修改。
如果需要修改文件内容,建议直接在全局搜索关键词。
]]>IE8+才会支持JSON对象。我们可以通过代码自己模拟原生的JSON对象:模拟原生JSON对象
[eval和new Function]
看模拟原生JSON对象的实现我们可以看到实现思路:
|
|
当我们实际的操作一下,还是会有些小问题的.
(1)利用eval()函数解析JSON对象:
|
|
这是为什么呢?其实是{}做的怪。{}的用处无非两个,(1)用于创建对象;(2)创建代码块,并且当{}位于语句的开头时,代码就会被当成代码块来解析。这里eval()中明显就是把对象当成代码块来解析了,所以就报错了。
解决方法:
|
|
(2)JSON.parse()不允许逗号结尾:
|
|
这是一个canvas标签:
|
|
控制它的宽高是要写在行内样式中的,像上面那样。这样我们就有了一个canvas元素,然后我们就可以去操作它了:
|
|
获取元素的同时,还要获取canvas的2D绘图环境。要是用于3D绘图的话,就要用WebGL了。
然后,我们要开始在画布上绘图了。它的画布是这样的网格:
2.1矩形
canvas中只支持这一种形状的函数,别的形状就都要自己组合来实现了。
|
|
其中的(x,y)是指矩形左上角的坐标。
2.2路径
1.首先,创建一条路径--beginPath()
2.然后,通过一些绘图的方法做一些绘图操作
3.然后关闭路径--closePath()
4.我们已经把路径创建好了,然后就是填充或者绘制路径到我们的画布上--stroke()/fill()
需要注意的是其中两个三角形,颜色不同,一不小心可能会出问题,所以我们有时可能需要save()和restore()函数的帮助来达到局部作用的效果。
canvas还提供了两个移动画笔的函数:
moveTo(x, y) //将画笔移动到指定的(x,y)的位置
lineTo(x, y) //在当前画笔的位置到指定的(x,y)位置画一条线
尝试一下moveTo()方法我们可以画个笑脸:
查看源码 运行结果
结合使用moveTo和lineTo方法,我们可以实现鼠标像画笔一样在画板上绘图的效果:
查看源码 运行结果
然后我们严格的按照上面说的规范步骤,1,2,3,4并结合画圆的函数,可以自己绘制一个钟表,稍加改进就是个嘀嗒嘀嗒走的时钟了:
查看代码 运行结果
2.3文字
fillText('要显示的文本',x坐标,y坐标)此方法不支持文本断行,要显示多行文本只能多次调用
通过fillText()方法我们可以在canvas画布上写文字:
查看源码 运行结果
2.4圆形和扇形
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
(x,y)--圆心坐标
radius--半径
startAngle--扇形的起始角度(弧度)
endAngle--扇形的终止角度(弧度)
anticlockwise--做图时是顺时针画(true)还是逆时针(false)画
结合对rgb颜色的相关操作,我们可以做出类似调色板的效果:
查看源码 运行结果
2.5不规则图形
我们可以通过画曲线来得到不规则的图形,canvas为我们提供了两个高大上的函数:
-------------------------------
#quadraticCurveTo(cp1x, cp1y, x, y)
(cp1x,cp1y)--控制点
此函数表示从当前的画笔位置到(x,y)画一条二次曲线
-------------------------------
#bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
(cp1x,cp1y)--控制点1 (cp2x,cp2y)--控制点2
此函数表示从当前的画笔位置到(x,y)画一条bezier曲线
-------------------------------
这两个曲线具体含义我也不太清楚,但大概是这个样子:
画个会话气泡试一下quadraticCurveTo函数:
查看源码 运行结果
画个心形试一下bezierCurveTo函数:
查看源码 运行结果
2.6渐变和阴影
#渐变:
var myGradient = ctx.createLinearGradient(x1, y1, x2, y2);
(x1,y1)--起点坐标 (x2,y2)--终点坐标
myGradient.addColorStop(0, "#BABABA");
--添加起始颜色
myGradient.addColorStop(1, "#636363");
--添加终止的颜色
-----------------------------
#阴影
ctx.shadowOffsetX = 10; // 设置水平位移
ctx.shadowOffsetY = 10; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度
ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色
一个也不太搭边儿的例子,不管怎么说,也用到了渐变呢,满是星星的星球:
查看源码 运行结果
这里面用到了clip()方法来实现星星,这跟某css属性clip-path比较神似,我以前尝试过:
请戳:源码 示例
2.7变换
canvas中有我们熟悉的几个变换函数:
|
|
几个关键函数:
|
|
通过getImageData()方法获取到图像对象,访问它的data属性就可以得到一个像素数组,我们对像素进行处理,使我们可以用canvas处理图像。
3.1 灰度效果
灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。
|
|
3.2 复古效果
复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。
|
|
3.3 反转效果
反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255-原值)
|
|
我尝试了一下灰度图的效果和反转图的效果: 查看源码
注意,在我们自己本地写demo准备运行查看结果的时候,getImageData()方法可能会有问题,比如说报这个错:Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data
我们知道这是域和本地运行等相关的问题,这时我们自己本地启用服务器,localhost访问就可以了。
3.4 拾色器
实现思路:通过getImageData(x,y,1,1)获得当前鼠标所在位置的一像素的图像对象,通过其data属性操作拿到它的像素值,也就是我们想得到的rgb值。
查看源码
3.5 放大镜
实际上drawImage方法可以有多个参数,提供更加丰富的功能:
|
|
各个参数就像下面的示意图这样:
然后我们就可以使用drawImage方法在原图像变换到绘制的图像中做一个等比放大的操作,就可以实现放大镜的效果啦: 查看源码
3.6图像的高斯模糊
其实,css中有一个兼容性不那么好的filter属性,可以简单的实现图像模糊的效果:
|
|
但是使用canvas可以实现真正意义上的高斯模糊(就是算法那种balabala的)。
这里有一个实现的很好的高斯模糊的js:StackBlur
使用它我们就可以轻松的实现图像的高斯模糊了:查看源码
canvas中绘图环境所有的属性和方法都可以在这里找到:CanvasRenderingContext2D interface
]]>取余运算符运算结果的正负号由第一个运算子的正负号决定,比如:
|
|
所以有时候对负数取余会出现错误,使用绝对值函数可以避免错误:
|
|
+运算符与其他运算符不太一样,我们知道它可以用来连接字符串操作,是因为用+运算符的时候它通常会将其他类型的值转为字符串,但是除了它比如说-运算符等都会将其他类型的值转换为数值,像这样:
|
|
当运算子中出现对象的时候:
|
|
则先调用该对象的valueOf方法。如果返回结果为原始类型的值,则转换为字符串;否则继续调用该对象的toString方法,然后转换为字符串。
但是:
|
|
这是为什么呢?此时{a:1}被当做了代码块处理,而这个代码块没有返回值,所以整个表达式就返回1了。但是放在了圆括号中的{a:1},因为js预期()中是一个值,所以它就又被当做对象处理了。
特殊表达式:
先调用valueOf()返回空数组本身,再调用toString(),返回空字符串。
|
|
[]得到’’,{}得到”[object Object]”
|
|
{}被视作代码块省略,+[]就是将[]转换为数值的意思了得到0.
|
|
同样{}被当做代码块省略了,+{}转数值得到NaN
|
|
如果第一个空对象不被当做空代码块的话:
|
|
此外,当+运算符作为数值运算符放在其他值前面的时候,可以用于将任何值转为数值,就像Number函数那样:
|
|
!取反运算符连续对同一个值进行取反运算等于将其转换为对应的布尔值,就像Boolean函数那样:
!!x
// 等同于
Boolean(x)
此外,如果我们想排除null这个对象,可以这样写:
|
|
这是因为:!!null 值是 false,其他的 object !!obj 值都是 true。
~运算符是根据值的二进制二进制形式进行运算的。
~ 3 // -4
它的运算原理就是根据数值的32位二进制整数形式运算,补码存储的原理如果是负数,需要将取反后的值减一再取反然后加上负号。
比较麻烦,但是我们可以记成一个值与它取反后的值相加等于-1.
~~2.9
// 2
两次否运算能够对小数取整,并且这是取整方法中最快的一种。
两次异或运算交换两个数的值:
|
|
左移0位可用于取整:
|
|
左移运算可以将颜色的RGB值转为HEX值:
|
|
右移运算可以模拟2的整除运算:
|
|
此外,void运算符的作用是用来执行一个表达式,然后返回undefined,而且它的运算符优先级也比较高void 4+7 实际上等同于 (void 4) +7。一般运算符是左结合的,但是=和三目运算符?:却是右结合的:
|
|
##一.使用XMLHttpRequest
从Ajax的工作原理来看,它是一种可以使用脚本操纵HTTP和Web服务器进行数据交换并且不会导致页面重载的技术。Ajax的核心就是XMLHttpRequest对象。
var xhr = new XMLHttpRequest();
这样就实例化了一个XMLHttpRequest对象,每个xhr对象都表示一个独立的请求响应对,通过这个对象的属性和方法我们可以查看请求的细节和得到响应的数据。
1.1 必备知识点
下面举个梨子:
|
|
从中可以看到一些xhr对象的方法和属性:
— xhr.setRequestHeader(“Content-Type”,”text/plain”);它用来设置请求头的信息,post请求通常会设置前面的Content-Type的请求头,比如说我想跨域发送请求,那你可能就要设置xhr.setRequestHeader(“Origin”,”url”)了(要真的跨域还需要在服务器端设置Access-Control-Allow-Origin)。但是并不能设置所有的请求头信息,你可以设置除了下面这些头之外的信息:Accept-Charset,Accept-Encoding,Connection,Content-Length,Cookie,Cookie2,Content-Transfer-Encoding,Date,Expect,Host,Keep-Alive,Referrer,User-Agent,Trailer,Transfer-Encoding,Upgrade,Via.
— xhr.getResponseHeader()和xhr.getAllResponseHeader()用来查询响应头信息。
— xhr.status(数字)和xhr.statusText(文本)返回HTTP状态码(200,404等);
— xhr.responseText(文本形式)和xhr.responseXML(document形式)得到响应主体;
— xhr.readyState得到一个整数,指定了HTTP请求的状态,有如下对应关系:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
常量 值 含义
-----------------------------------------------------------------------------
UNSENT 0 open()尚未调用
OPENED 1 open()已调用
HEADERS_RECEIVED 2 接收到头信息
LOADING 3 接收到响应主体
DONE 4 响应完成
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
— xhr.overrideMimeType(‘text/plain;charset=x-user-defined’);overrideMimeType方法用来指定服务器返回的数据的Mime类型;
— xhr.responseType属性,它用来指定服务器返回的数据的类型,xhr2允许用户自行设置这个属性了(上面的overrideMimeType方法就是一般在不支持这个属性的情况下使用的)。
xhr.responseType=’text’(字符串)/‘arrayBuffer’/‘blob’(二进制数据)/‘document’/‘json’(JSON对象)
— 事件:XMLHttpRequest对象原本只有一个事件xhr.onreadystatechange = function(){},但是XMLHttpRequest2扩展了几个新的事件:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
事件 描述
------------------------------------------------------------------------------
onloadstart 请求开始时触发
onprogress 开始加载并发送数据时触发
onabort 请求终止时出发,比如调用了abort()方法
onerror 请求失败时触发
onload 请求成功完成时触发
ontimeout 自定义的超时时间超过,请求还没完成时触发
onloadend 请求完成时触发(success or failure)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1.2 send()方法
请求中的send()方法,通常在发送POST请求时用于发送主体数据,发送GET请求时通常为空。
在XHR2中send()方法可以发送很多类型的数据。
|
|
通过Ajax提交表单数据还是很有意义的。传统的做法中,点击页面中表单的submit按钮,需要跳转到一个空页面,然后再对原页面的数据进行处理。ajax则不用,可以直接在原页面进行提交后的处理。
发送FormData类型的数据为我们提供了便利:
|
|
1.3 再看CORS
CORS(跨域资源共享),它的出现就是为了解救Ajax受限于同源策略,实现跨域。
预检机制:
我们可能只知道要实现跨域要请求头带上Origin头,并且服务器响应Access-Control-Request-Method头表示同意跨域的请求。但其实我们忽略了它背后的一个预检机制,也就是说会有类似这样一个预检请求:
1 OPTIONS /resources/post-here/ HTTP/1.1
2 Host: www.google.com
3 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5 Accept-Language: en-us,en;q=0.5
6 Accept-Encoding: gzip,deflate
7 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
8 Connection: keep-alive
9 Origin: http://www.example.com
10 Access-Control-Request-Method: POST
11 Access-Control-Request-Headers: X-PINGOTHER
OPTIONS就是告诉我们这是一个“预检”请求。里面有关键的Origin头信息。
|
|
这两个头信息就告诉服务器,如果我发送请求的话将会是POST请求,我还可能自己定义个X-PINGOTHER的请求头信息。
同样的,服务器也会响应这个预检的请求:
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://www.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
Access-Control-Max-Age: 1728000
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
我们期待服务器同意我的跨域请求的Access-Control-Allow-Origin头也有了,告诉我服务器同意了。也同意了我想自定义一个请求头信息的愿望。
下面还有一个响应头信息:
Access-Control-Max-Age: 1728000
它呢,是用来控制这条预检请求的缓存时长的,在这1728000秒之内,都不用再发送预检请求了。
因为整个预检的过程都是浏览器在后台神不知鬼不觉完成的,所以我们都不知道。
CORS中的Cookie:
CORS机制默认是不会发送cookie信息和HTTP的认证信息的,除非我们改变设置。可以这样:
xhr.withCredentials = true;
同时服务器响应:
Access-Control-Allow-Credentials:true //这里值不能为*必须明确指定域名
这时,我们在发送请求的时候才会捎带上cookie的信息,而且这里的cookie也遵循同源策略,只有服务器域名下的cookie信息才会被捎带。
##二、HTTP请求和响应
因为Ajax就是用来与服务器通信的,那么这里它就离不开HTTP,也就会去请求然后获得响应。这里稍微详细的了解下请求头与响应头相关的信息。
一个 HTTP请求由4部分组成:
– HTTP请求方法或“动作”;
– 正在请求的URL;
– 一个可选的请求头集合,其中可能包括身份验证信息;
– 一个可选的请求主体 ;
服务器返回的HTTP响应包含3部分:
– 一个数字和文字组成的状态码,用来显示请求的成功和失败
– 一个响应头集合
– 响应主体
我在网上找了一个参数尽可能多的请求,下面是它的请求头信息和响应头信息:
2.1 Request Headers中的一些参数:
含义:浏览器支持的 MIME 类型分别是 text/html、application/xhtml+xml、application/xml 和 /,优先顺序是它们从左到右的排列顺序。
详解:
– Accept表示浏览器支持的 MIME 类型;
– MIME的英文全称是 Multipurpose Internet Mail Extensions(多功能 Internet 邮件扩充服务),它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器;
– text/html,application/xhtml+xml,application/xml 都是 MIME 类型,也可以称为媒体类型和内容类型,斜杠前面的是 type(类型),斜杠后面的是 subtype(子类型),type 指定大的范围,subtype 是 type 中范围更明确的类型,即大类中的小类;
– Text用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
– text/html表示 html 文档;
– Application:用于传输应用程序数据或者二进制数据;
– application/xhtml+xml表示 xhtml 文档;
– application/xml表示 xml 文档;
– q是权重系数,范围 0 =< q <= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容,若没有指定 q 值,则默认为1,若被赋值为0,则用于提醒服务器哪些是浏览器不接受的内容类型。
2.Accept-Encoding: gzip, deflate
含义:标示浏览器支持的压缩编码是gzip和deflate和sdcn。
3.Accept-Language:zh-CN,zh;q=0.8
含义:浏览器支持的语言,zh-CN是简体中文,zh是中文。
4.Cache-Control:max-age=0(请求头中的Cache-Control)
含义:Cache-Control头是用来在请求/响应这个过程中控制缓存的。
他可以有的参数:
max-age=0单位是秒,它表示客户端可接受的响应等待时间;
max-stale表示客户端愿意接受一个响应,即使它已经超过了它新鲜的寿命(可以有值也可以没有值);
min-fresh=10他表示客户端愿意接受一个响应的保鲜寿命不小于目前的年龄加上指定的时间在几秒钟内;
no-cache表示不接受缓存的响应;
no-store表示缓存不可以保存请求和响应的任何部分;
only-if-cache:它表示客户端只想要获得一个被缓存起来了的响应。
5.Host
含义:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号.
6.Content-Type:application/x-www-form-urlencoded
含义:请求头的Content-Type定义传递到服务器的数据类型,数据由服务器端处理!Content-Type后面的值就是一个MIME类型。application/x-www-form-urlencoded实际上就是指表单提交的数据,如果上传附件,就会是multipart/form-data。响应头的Content- Type定义返回到客户端的数据类型。
其他一些常见易理解的参数,这里就不列举啦。
2.2 Response Headers中的一些参数:
1.Accept-Ranges:bytes
含义:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
2.Cache-Control:Public
public(可以用 Cached 内容回应任何用户)
private(只能用缓存内容回应先前请求该内容的那个用户)
no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
max-age:(本响应包含的对象的过期时间)
ALL: no-store(不允许缓存)
3.ETag
含义:它是一个对象的标志值,用于确认请求的文件是否被更改。比如一个 html 文件,如果被修改了,其 Etag 也会别修改,所以,ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给 WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。
4.Expires
含义:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求
5.Last-Modified
含义:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等
2.3 GET请求和POST请求的区别
也许你也曾想过GET和POST方法的区别,这里整理一下我了解到的:
GET:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GET方法用于向指定的资源或服务器请求数据
--------------------------------------------------------------------------------
1.GET请求可以被浏览器缓存
2.GET请求保留在浏览器的历史记录中
3.GET请求可以被收藏为书签
4.GET请求不应该在处理敏感数据时使用,它的安全性有待商榷
5.GET请求有长度的限制
6.GET请求应当只用于取回数据
7.GET请求从来没有主体,需要的查询参数要编码放在url后面作为查询字符串
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
POST:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
POST方法向指定的资源或服务器提交要被处理的数据
------------------------------------------------------------------------------------
1.POST请求不会被缓存
2.POST请求不会保留在浏览器的历史记录中
3.POST请求不能被收藏为书签
4.POST请求对数据的长度没有要求
5.POST请求通常有主体,用来提交要被处理的数据,xhr.send('数据')
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如果想更加详细的学习HTTP协议相关的内容可以查看RFC:RFC7230 RFC7231 RFC7232 等等
##三.JQuery中的Ajax
我们一般实际应用的时候大部分都是jQuery或Zepto中的Ajax了。
我给自己列了些细节或要点,有时很有用,有时会避免错误:
1.$.ajax()会返回创建的XMLHttpRequest对象,然后我们可以就可以应用xhr对象的一些属性或方法了,但大多数情况下我们不会用到,像这样:
htmlobj=$.ajax({url:"/jquery/test1.txt",async:false});
$("#myDiv").html(htmlobj.responseText);
2.cache:false
有时候我们发送了个请求,返回的数据也得到了,但是后端同学在相同的接口中准备返回给你跟之前不同的数据比如说多一个字段,或少一个字段时。你肯定期待拿到新的数据了,但如果的你请求是get请求的话那么浏览器就会缓存你的Ajax请求,post请求一般不存在这个问题,于是你就纳闷了为什么数据没有变化。于是我们可以设置cache:false,使每次都发送请求而不是取缓存中的。
3.context:document.body
context参数可以指定回调函数的上下文,使回调函数中的$(this)指向context参数对应的DOM元素。
4.dataType:’xml’/‘jsonp’/‘html’/‘script’/‘json’/‘text’
这是最简单务实的一个参数了,用于定于预期服务器返回的数据类型。设置值为‘script’时,将返回纯文本js代码,并且不会自动缓存结果,除非显示的设置cache为true,并且所有的POST请求都会被转为GET请求。设置值为‘jsonp’时,如果我们自己没有显示的定义回调函数的名字,jQuery会自动的帮我们添加,以正确的执行回调函数。这样我们回调函数的参数data就是json类型的数据了。
##四.待扩展和实战的学习要点
进一步准备学习和实战练习的:
利用XMLHttpRequest对象特别是扩展了的二级XMLHttpRequest对象,我们还可以做很多事情,比如说:①Ajax上传文件(可以使用FormData接口或File API)②获得progress元素的上传进度(xhr对象的upload属性的progress事件)③使用abort()方法终止请求和实现超时 等等。
HTTP用来在客户端和服务器之间建立连接进行交流,那么利用HTTP请求头信息和响应头信息其实也能做很多事情,比如:①正确的配置信息头实现请求的缓存,加快响应用户的速度②控制安全的请求同服务器交互等等。
Jquery源码中ajax的实现方式,思想学习以及与Zepto中Ajax实现的不同。
参考资料&相关阅读:
Ajax-Javascript标准参考教程
MDN UsingXMLHttpRequest
使用FormData对象
Web API接口查询表
Using CORS
http协议请求响应头中参数的疑问
JQuery源码分析
Zeptojs Ajax API
这个肯定会:
|
|
但不能只会,很多情况下需要判断的不是字符串,对不?那如果变成对象只会判断:
|
|
那在好多情况下就又会进坑了…
为什么呢?去这儿看看:关于x==y的比较行为
$.isPlainObject()
jQ中的这个方法在对象是通过{}或new Object()创建的的时候会返回true。Zepto中
也有这个方法,大体相同。
源码是这样的:
|
|
可以试试了:
|
|
判断一个对象是否为空对象:
|
|
不过有时候它也挺坑爹的:
|
|
其实,我们可以巧妙的应用toString()方法来判断数值类型,不管是基本的值类型还是对象:
|
|
稍微整理一下就可以像我们想要得到的那样来判断数值类型了,特殊的null和undefined也不会落下:
|
|
具体情况还是要具体分析,头脑清晰想清楚再判断好,再去做接下来的事情。少走些弯路。
]]>PPI是一个度量单位,是像素密度单位,它表示了现实世界一英寸内的像素数,因此它决定了屏幕的显示质量。
像我们常说的1024*768其实是指的屏幕分辨率,对应在现实中的分辨率就用PPI作为度量单位,可以举个例子来说明:
|------------------------------------|
|如果显示器的屏幕大小是14英寸(对角线的长度)纵横比是3:4-->
|那么水平方向上的长度就为:14*(4/5)=11.2 英寸 (1英寸=0.762寸)
|从而我们常说的1024对应现实世界的分辨率就为:1024/11.2 = 91.4PPI
|------------------------------------|
所以通常要分辨清楚,像我们说的1024768和iPhone5s的6401136他们不是对应PPI这个单位的。
正是因为不相同,存在这样的对应关系,所以在终端上必要的时候就会做PPI的适配,以Retina屏为例子:
-->我们不想文字在Retina屏上变小(因为在相同尺寸的屏幕下,Retina屏拥有比非Retina屏更多的物理像素,就是我们现实世界中的像素数,所以相同大小的字在Retina下会变小),所以为了做适配,我们可以采用类似媒体查询的办法来改变字体的大小。
|-PS-|:Retina显示屏
定义:就是具备足够高像素密度而使到人体肉眼无法分辨其中单独像素点的液晶屏,就像最早的iPhone4的屏幕。它的屏幕分辨率为960×640(每英寸像素数326ppi)。
我觉得最大的区别就是:因为我们看到的图像都是通过物理像素呈现的,所以像素越密集图像就越清晰,而所谓的Retina显示屏就是在相同尺寸的屏幕下比非Retina的屏幕具备更多的物理像素。
##二.设备像素比率(Device Pixel Ratio,DPR)
定义:
devicePixelRatio指的是window.devicePixelRatio, 被所有WebKit浏览器以及Opera所支持,window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例,即:devicePixelRatio=设备物理像素/设备独立像素。
它表示的就是物理像素与逻辑像素(px)的对应关系。
举个例子:
以iPhone为例,retina下devicePixelRatio=1,非retina下devicePixelRatio=2,这是因为无论是retina还是非retina屏,竖屏下,设备独立像素都是320,而它们的设备物理像素分别为640、320。
这边还有更加详细的相关阅读:设备像素比devicePixelRatio的简单介绍 devicePixelRatio=1.5引发的问题
于是也就有了DPR适配的问题,因为存在设备像素比率这个东西,所以当我们遇到那个经典的1px问题(无非就是设计师希望在任何的屏幕上都有一条1物理像素的边),要做的就多了。
要先说下分辨率(Resolution),它就是指屏幕区域的宽高所占的像素数。分辨率说全了就是设备的分辨率,这两个是一回事。这个分辨率是指每英寸的面积上可产生的像素点,分辨率越高代表可以将画面显示的更精细(有时候获取的显示器分辨率,其实是指桌面设定的分辨率,而不是显示器的物理分辨率。大多数情况下,我们设置的分辨率与物理分辨率一致,显示效果才最佳)。
其实这里说的分辨率(Resolution)在绝大多数的情况下跟我们题目上的设备像素是一个东西,名字的不同而已。
好,下面就专心说设备像素/css像素。
1.我们姑且认定设备的pixels为正确(标准)的pixels宽度。这些pixels决定了你工作所用的那些设备上正式的分辨率。在大多数情况下,能够从screen.width/height上取出具体值;
2.现代浏览器上的缩放,是基于“伸展”pixels。结果是,html元素上的宽度并没有因为缩放200%而由128pix变成256px,而是真实的pixels的被计算成了双倍。html元素在形式上依然是128CSS的pixels,即便它占用了256设备的pixels;
3.图例:
下列图片将清楚的解释这个概念。如图,有4个1像素,缩放为100%的html元素,CSS的pixels完整的和设备的pixels重叠
当我们缩小浏览器时,CSS的pixels开始收缩,导致1单位的设备的pixels上重叠了多个CSS的pixels,如下图:
同理,放大浏览器时,相反的事情发生了,CSS的pixels开始扩大,导致1单位的CSS的pixels上重叠了多个设备的pixels,如下图:
4.总体而言,你只需要关注CSS的pixels,这些pixels指定你的样式被如何渲染,设备的pixels几乎对你毫无用处。但对用户而言却不是这样。用户会缩放页面,直到他能舒服的阅读内容。但是你不需关心这些缩放级别。浏览器会自动的保证你的CSS的pixels会被伸展还是收缩;
5.在缩放级别为100%时,1单位的CSS的pixel是严格相等于1单位的设备pixel。
6.上面有说道,页面的清晰和模糊其实可以通过设备像素和css像素的关系来解释。那么这里也要注意下Retina屏,不然稍不注意,图可能会糊掉。
非retina屏下,一个css像素“覆盖”在一个设备物理像素上;
retina屏下,一个css像素“覆盖”在四个设备物理像素上,实质是一个css像素被瓜分成了四份,效果就变糊了。
原理就像下面这样:
1.em
em是相对单位,参考物是父元素的font-size,同百分比方式的单位相同,具有继承的特点,如果字体大小是16px(浏览器的默认值),那么 1em = 16px。 如果父元素设置了font-size:62.5%,那么相应的1em=10px了。
这里有篇文章研究的比较仔细:关于webapp中的文字单位的一些倒腾
2.rem
rem也是相对单位,不过总是相对于根元素的字体大小,也就是元素。
现在越来越多的人采用rem在不同的设备间进行布局了,可以通过js动态的改变元素的font-size,或是通过媒体查询来动态改变元素的font-size的大小,来适配不同设备的不同屏幕大小,实现跨终端的目的,而且支持度也越来越好了。
3.vw和vh
vw Viewport宽度, 1vw 等于viewport宽度的1%;
vh Viewport高度, 1vh 等于viewport高的的1%;
4.vmin和vmax
vw和vh对应于viewport的width和height,而vmin和vmax分别对应于width、height中的最小值和最大值,例如如果浏览器的宽/高被设置为1000px/600px,那么
1vmin = 600 * 1/100;
1vmax = 1000 * 1/100
|-视口viewport(这里且先说pc相关的viewport)-|
viewport的定义是严格的等于浏览器的窗口,它不是一个HTML的概念,所以我们不能通过css去修改它。
实际上,viewport的功能在于控制网站的最高block容器,那就是元素。也就是说元素为viewport宽度的100%。虽然我们知道document.documentElement实际上就是元素,但是document.documentElement. clientWidth/Height给出的实际是viewport的尺寸,而不是元素,不管元素的尺寸如何改变,都只会得到viewport的尺寸。那我们该如何获取元素的尺寸呢,可以使用document.documentElement.offsetWidth/Height,但还是有bug,IE用这个值标示viewport的尺寸而非 。
|-viewport(然后放开了的说下我学习和理解到的跨终端相关的viewport)-|
1.两种viewport:
虚拟的viewport#visualviewport --visualviewport是当前显示在屏幕上的部分页面。用户会滚动页面来改变可见部分,或者缩放浏览器来改变visualviewport的尺寸。window.innerWidth/Height返回visualviewport的尺寸。
布局的viewport#layoutviewport--css布局通常都是按照layoutviewport来定义,而且比visualviewport宽很多。同时元素的宽度也是继承于layoutviewport。那么layoutviewport有多宽呢?每个浏览器都不同。iPhone上的Safari使用980px、Opera 850px,安卓的Webkit核心800px,IE974px。浏览器已经选择好他们的layoutviewport的尺寸,它完整的覆盖了最小缩放模式下的移动浏览器的屏幕。document.documentElement.clientWidth/Height传递layoutviewport的尺寸。
2.和pc浏览器一样,screen.width/height标示了设备屏幕的尺寸,以设备的pixels度量。如果需要知道当前visualviewport相对于layoutviewport的距离。这就是滚动位移,如同在桌面浏览器一样,使用window.pageX/YOffset存储。和在桌面系统一样,document.documentElement.offsetWidth/Height给出了元素以CSS的pixels度量的尺寸。
上面内容只是基本,并不完整,不同浏览器的兼容问题还需要进一步研究,详细阅读请看:A Table of two viewports-part one 当然第二部分也非常值得一看: A Table of two viewports-part two
quirksmode上的一个非常全的viewport相关的兼容性表,可用于适配时查看:http://www.quirksmode.org/mobile/tableViewport.html
其中涉及到的页面元素大小偏移相关我之前也有整理,没那么深入,倒也通俗易懂: 页面元素坐标和偏移相关整理
我了解到的定义是:
+--width/height使用以CSS的pixels度量的layoutviewport,通俗的说就是页面内容的宽度;
+--device-width/height使用以设备的pixels度量的设备屏幕(device screen);
#--width/height 反映document. documentElement. clientWidth/Height的值;
#--device-width/height 反映screen.width/height;
但上面只是普遍情况,如果稍在ios设备下尝试下,就能发现事实跟上面说的不一样。
在某些设备下:screen.width == 设备的物理分辨率 / window.devicePixelRatio。具体情况还需要详细的测试。
上面也还只是列出了相关问题的基本了解与学习,在这个过程中更加发现,需要深入研究与学习的知识点还是很多的。
比如说标签相关,还有1px的问题,都是值得深入学习的。
后续继续持续学习,逐步完善。
]]>