整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

打造网页版聊天页面的几个知识点

近来一直在做微信开发,涉及的东西很多,但是思路基本是从微信接口拿数据这样一个流程。在开发过程中,顺便写了一个聊天页面。个人感觉还不错,所以把其中遇到的几个知识点分享给大家。

整体的界面就是上面的样子,排版方面的知识就不多说了,毕竟我也不是做前端的,而且很多样式都是直接从官网拿过来。还是主要说一说流程逻辑方面的知识。其实并没有太深的学问,只要有基础的Js,循环,判断语句就可以了。我主要想表达的还是实战思路。接下来我先把问题抛出来,如果已经想到了很好的方法大可不必再浪费时间看下去了。

1,中框部分的聊天记录显示问题(各部分均为独立iframe框架)

难点:因为显示的条数受限,假设只显示最近5条,那么应该是用时间倒序获取5条数据,这样能实现最近5条数据,但是显示结果会是自上而下从晚到早。相反,如果按照时间顺序提取5条,那么显示顺序没问题,可是获取的5条数据却不是最近的而是最早的。

2,与第1点同步的会出现每条发送信息的时间,但是每条数据后面跟着一串‘2017-01-20 15:30:23’肯定会很难看。理想的效果是,短时间内(例如半小时内)就显示一次发送时间,当天聊天记录就只显示时分秒,今天以前的聊天就显示年月日时分秒。如果判断是否当天还好说,可是判断是否距离上一条记录(严格来说是上一条显示时间的记录)半小时以内就要动动脑筋了。

3,中框的聊天信息展示肯定要随时更新的,如果你发送一条信息用post提交,相当于刷新一次页面还好理解。但是如果是收到一条信息又怎么能即时刷新呢。

4,倘若中框的聊天记录有10条,窗口大小只能显示5条,怎么能让它显示到最底部一条信息。当然,你可以只让它获取到最近5条数据,但是如果某一条数据内容特别长,还是会出现滚动条,还是不是显示页面底部。

5,发送信息采用ctrl+enter发送,因为如果只按enter发送,就不能换行了。网上可以搜到相关代码,但是很有可能出现ctrl+enter键按下时,打开新的窗口。所以我在下面会放上测试好的代码。

6,当聊天页面处于关闭状态,收到新信息会有消息提醒。这一点比较容易就不说了。另外一种情况,你在聊天页面与某一个好友聊天时,另一个或多个好友来消息时,也需要在对应的头像和分组菜单有消息提醒。

7,发送消息方式一般采用post提交,提交后页面刷新也能获取到最新消息。但是如果提交信息用的是其它接口(比如用微信公众号发送),就会首先获取到接口返回的数据后才能算发送成功,才能进行写入数据库或其它操作。在这个过程可能会3到5秒,体验效果就会变差。所以建议采用ajax异步提交,并且提交后利用Js显示到聊天主窗口(发送中状态),当收到ajax发送成功的反馈时刷新页面,否则提示发送失败。

针对以上的问题,在下面一一解答或者直接粘贴代码。

问题一思路:把获取到的最近5条信息遍历出来,逆序赋值给一个变量,然后把这个变量当成html元素放到页面。

$res= mysql_query(“select * from msg where sid= 23 and user=23 order bycreat_time limit 0,5”);//从数据库获取最近5条数据

$str= ‘’;//声明变量

While($rows = mysql_fetch_array($res))

{

$str = “<div><span>{$rows[‘name’]}</span><span>{$rows[‘con’]}</span></div>”.$str;

}

Html 部分

<divclass=”content”>

{$str}

</div>

问题二思路:是否当天可以用拿到的时间与当天日期进行比较(如果字段有时分秒可以截取前10位),判断是否与上一条显示时间相隔半小时,就需要先声明一个时间变量,当每次需要显示时间时就赋值一次。

这里还有一个问题,因为显示时第一条信息是5条里面最早的,最后一条是最近的,然后获取数据的顺序正好相反。所以判断时间是否相隔半小时,是拿到的一条时间与下一条时间做比较。这当然是不可能的。那么我想到的方法先把获取的数据赋值给数组,再用数据遍历输出。

问题三思路:在<head>里加入一行代码

<metahttp-equiv="Refresh" content="5;URL=imshow.php">

让这个页面每5秒刷新一次。这当然是个方法,只是不太好。原因很简单,页面会不断的闪动也会占用服务器承载量。所以建议用ajax获取是否有新消息,如果有,则启动刷新。

functionget_msg(){

var str = '';

$.get("./ajax/ajax_wechat_new_list.php?uid="+uid+"&mid="+mid,function(data,status){

if(data>0){

window.location.reload();

}

});

setTimeout(function(){

get_msg();

},3000)

}

get_msg();

问题四思路:这个问题是个很实用的问题,曾很困扰。我尝试用模拟点击事件,自动运行js效果都不太好。其实最简单的方法是在页面末端加一个全局选择器,例如id.

<astyle="text-indent:-9999px" id="go_foot"href="#go_foot"></a>

然后在url地址尾处加一个#go_foot,,,倘若不好用的话,再设置瞄点模拟点击。

document.getElementById('go_foot').click();

问题五思路:

$("#sms_content").keyup(function(event){

if(event.ctrlKey && event.which ==13) //13等于回车键(Enter)键值,ctrlKey 等于 Ctrl

{

$('#send').trigger("click");

}

});

备注:其中‘sms_content’是input提交标签的Id, keyup(松开按键)可以改为keydown(按下键盘),但是会出现打开新窗口的情况。

问题六思路:预先给每个好友设置好提醒的html元素(id名需要与该好友的id相关联以便查找),并处理隐藏状态。当用ajax获取到该好友的新消息时,则找到对应标签变为显示状态。

functionget_msg(){

var str = '';

$.get("./ajax/ajax_wechat_notice1.php?uid="+uid+"&show="+show,function(data,status){

if(data!=0){

varmsg = eval("("+data+")");

for(vari=0;i<msg.length;i++)

{

varmid = msg[i].id;

vartime = msg[i].time;

varcon = msg[i].msg.substring(0,16)+'...';

$("#show_msg"+mid).show();

$("#show_msg"+mid).parent().prevAll('.time_tag').text(time);

$("#show_msg"+mid).parent().prevAll('.ext').children('.new_msg').text(con);

$("#show_msg"+mid).parent().parent().parent().prev().prev('.group_user').children('img').show();

}

}

});

setTimeout(function(){

get_msg();

},10000);

}

get_msg();

备注:以上代码在消息提醒的同时,也会获取到未读消息的发送时间和内容,需要在相关页面设置,仅供参考。

问题七思路:首先在中框聊天列表的页面里,预先插入一条备用聊天记录(包括发送人,发送信息,发送中状态图标),使其隐藏状态。当点击发送时,需要处理几个动作。a,利用ajax把文本框内容发送,b,文本框的内容赋值给备用聊天记录,c,令备用聊天记录可见,同时文本框内容清空d,模拟点击事件让聊天页面显示底部,f,获取ajax发送反馈,如果成功则刷新聊天记录窗口。如果失败利用js把发送中图标改为失败图标,并且弹出发出失败的反馈信息。

多大公司面试喜欢问这样一道面试题,输入URL到看见页面发生了什么? 简单来说,共有以下几个过程:

  1. DNS解析
  2. 发起TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 连接结束。

DNS解析

DNS解析实际上就是寻找你所需要的资源的过程。假设你输入www.baidu.com,而这个网址并不是百度的真实地址,互联网中每一台机器都有唯一标识的IP地址,这个才是关键,但是它不好记,乱七八糟一串数字谁记得住啊,所以就需要一个网址和IP地址的转换,也就是DNS解析。下面看看具体的解析过程

具体解析

DNS解析其实是一个递归的过程

输入www.google.com网址后,首先在本地的域名服务器中查找,没找到去根域名服务器查找,没有再去com顶级域名服务器查找,,如此的类推下去,直到找到IP地址,然后把它记录在本地,供下次使用。大致过程就是.-> .com ->google.com. -> www.google.com。 (你可能觉得我多写 .,并木有,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上)DNS优化

既然已经懂得了解析的具体过程,我们可以看到上述一共经过了N个过程,每个过程有一定的消耗和时间的等待,因此我们得想办法解决一下这个问题!

DNS缓存

DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存

DNS负载均衡

不知道你们有没有注意这样一件事,你访问baidu.com的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问,假设只有一个服务器,那它的性能和存储量要多大才能支撑这样大量的访问呢?DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡

发起TCP连接

TCP提供一种可靠的传输,这个过程涉及到三次握手,四次挥手,下面我们详细看看 TCP提供一种面向连接的,可靠的字节流服务。 其首部的数据格式如下

字段分析

  • 源端口:源端口和IP地址的作用是标识报文的返回地址。
  • 目的端口:端口指明接收方计算机上的应用程序接口。

TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

  • 序号:是TCP可靠传输的关键部分。序号是该报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节都有一个序号。比如一个报文段的序号为300,报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。
  • 确认序号:即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
  • 首部长度/数据偏移:占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8=60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。
  • 保留:占6位,保留今后使用,但目前应都位0。
  • 控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。
  • 紧急URG:当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据
  • 确认ACK:仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1。
  • 推送PSH:当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1。
  • 复位RST:当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接。
  • 同步SYN:在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1。
  • 终止FIN:用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放。
  • 窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。
  • 校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
  • 紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
  • 选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
  • 数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

需要注意的是: (A)不要将确认序号Ack与标志位中的ACK搞混了。 (B)确认方Ack=发起方Req+1,两端配对。

三次握手

第一次握手:

客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:

服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:

客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

为什么会采用三次握手,若采用二次握手可以吗? 四次呢?

建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。

采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。失效的连接请求报文段是指:主机A发出的连接请求没有收到主机B的确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。

采用两次握手不行,原因就是上面说的失效的连接请求的特殊情况。而在三次握手中, client和server都有一个发syn和收ack的过程, 双方都是发后能收, 表明通信则准备工作OK.

为什么不是四次握手呢? 大家应该知道通信中著名的蓝军红军约定, 这个例子说明, 通信不可能100%可靠, 而上面的三次握手已经做好了通信的准备工作, 再增加握手, 并不能显著提高可靠性, 而且也没有必要。

四次挥手

数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,假设客户端主动关闭,服务器被动关闭。

第一次挥手:

客户端发送一个FIN,用来关闭客户端到服务器的数据传送,也就是客户端告诉服务器:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,客户端依然会重发这些数据),但是,此时客户端还可以接受数据。 FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

第二次挥手:

服务器收到FIN包后,发送一个ACK给对方并且带上自己的序列号seq,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

第三次挥手:

服务器发送一个FIN,用来关闭服务器到客户端的数据传送,也就是告诉客户端,我的数据也发送完了,不会再给你发数据了。由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

第四次挥手:

主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些

至此,完成四次挥手。

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么建立连接是三次握手,关闭连接确是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

发送HTTP请求

首先科补一个小知识,HTTP的端口为80/8080,而HTTPS的端口为443

发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由请求行请求报头请求正文组成。

请求行

请求行的格式为Method Request-URL HTTP-Version CRLF eg: GET index.html HTTP/1.1 常用的方法有: GET,POST, PUT, DELETE, OPTIONS, HEAD。

常见的请求方法区别

这里主要展示POST和GET的区别

常见的区别

  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。

注意一点你也可以在GET里面藏body,POST里面带参数

重点区别

GET会产生一个TCP数据包,而POST会产生两个TCP数据包。

详细的说就是:

  • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
  • 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

注意一点,并不是所有的浏览器都会发送两次数据包,Firefox就发送一次

请求报头

请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。

从图中可以看出,请求报头中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。

请求正文

当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置Content-Type: application/json。

更重要的事情-HTTP缓存

HTTP属于客户端缓存,我们常认为浏览器有一个缓存数据库,用来保存一些静态文件,下面我们分为以下几个方面来简单介绍HTTP缓存

  • 缓存的规则
  • 缓存的方案
  • 缓存的优点
  • 不同刷新的请求执行过程

缓存的规则

缓存规则分为强制缓存协商缓存

强制缓存

当缓存数据库中有客户端需要的数据,客户端直接将数据从其中拿出来使用(如果数据未失效),当缓存服务器没有需要的数据时,客户端才会向服务端请求。

协商缓存

又称对比缓存。客户端会先从缓存数据库拿到一个缓存的标识,然后向服务端验证标识是否失效,如果没有失效服务端会返回304,这样客户端可以直接去缓存数据库拿出数据,如果失效,服务端会返回新的数据

强制缓存的优先级高于协商缓存,若两种缓存皆存在,且强制缓存命中目标,则协商缓存不再验证标识。

缓存的方案

上面的内容让我们大概了解了缓存机制是怎样运行的,但是,服务器是如何判断缓存是否失效呢?我们知道浏览器和服务器进行交互的时候会发送一些请求数据和响应数据,我们称之为HTTP报文。报文中包含首部header和主体部分body。与缓存相关的规则信息就包含在header中。boby中的内容是HTTP请求真正要传输的部分。举个HTTP报文header部分的例子如下:

我们依旧分为强制缓存和协商缓存来分析。

强制缓存

对于强制缓存,服务器响应的header中会用两个字段来表明——Expires和Cache-Control。

Expires

Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差,另一方面,Expires是HTTP1.0的产物,故现在大多数使用Cache-Control替代。

Cache-Control

Cache-Control有很多属性,不同的属性代表的意义也不同。

  • private:客户端可以缓存
  • public:客户端和代理服务器都可以缓存
  • max-age=t:缓存内容将在t秒后失效
  • no-cache:需要使用协商缓存来验证缓存数据
  • no-store:所有内容都不会缓存。

协商缓存

协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。

对于协商缓存来说,缓存标识我们需要着重理解一下,下面我们将着重介绍它的两种缓存方案。

Last-Modified

Last-Modified:服务器在响应请求时,会告诉浏览器资源的最后修改时间。

  • if-Modified-Since:浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。 从字面上看,就是说:从某个时间节点算起,是否文件被修改了
  • 如果真的被修改:那么开始传输响应一个整体,服务器返回:200 OK
  • 如果没有被修改:那么只需传输响应header,服务器返回:304 Not Modified
  • if-Unmodified-Since:从字面上看, 就是说: 从某个时间点算起, 是否文件没有被修改
  • 如果没有被修改:则开始`继续'传送文件: 服务器返回: 200 OK
  • 如果文件被修改:则不传输,服务器返回: 412 Precondition failed (预处理错误)

这两个的区别是一个是修改了才下载一个是没修改才下载。

Last-Modified 说好却也不是特别好,因为如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。为了解决这个问题,HTTP1.1推出了Etag。

Etag

Etag:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)

  • If-None-Match:再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。
  • 不同,说明资源被改动过,则响应整个资源内容,返回状态码200。
  • 相同,说明资源无心修改,则响应header,浏览器直接从缓存中获取数据信息。返回状态码304.

但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了。

缓存的优点

  • 减少了冗余的数据传递,节省宽带流量
  • 减少了服务器的负担,大大提高了网站性能
  • 加快了客户端加载网页的速度 这也正是HTTP缓存属于客户端缓存的原因。

不同刷新的请求执行过程

浏览器地址栏中写入URL,回车

  • 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。(最快)

F5

  • F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就战战兢兢的发送一个请求带上If-Modify-since。

Ctrl+F5

  • 告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作.

服务器处理请求并返回HTTP报文

它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,我使用过的Web服务器有Tomcat, Nginx和Apache等等 HTTP报文也分成三份,状态码响应报头响应报文

状态码

状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 1xx:指示信息–表示请求已接收,继续处理。
  • 2xx:成功–表示请求已被成功接收、理解、接受。
  • 3xx:重定向–要完成请求必须进行更进一步的操作。
  • 4xx:客户端错误–请求有语法错误或请求无法实现。
  • 5xx:服务器端错误–服务器未能实现合法的请求。 平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500

常见状态码区别

200 成功

请求成功,通常服务器提供了需要的资源。

204 无内容

服务器成功处理了请求,但没有返回任何内容。

301 永久移动

请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。

302 临时移动

服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

304 未修改

自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。

400 错误请求

服务器不理解请求的语法。

401 未授权

请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。

403 禁止

服务器拒绝请求。

404 未找到

服务器找不到请求的网页。

422 无法处理

请求格式正确,但是由于含有语义错误,无法响应

500 服务器内部错误

服务器遇到错误,无法完成请求。

响应报头

常见的响应报头字段有: Server, Connection...。

响应报文

你从服务器请求的HTML,CSS,JS文件就放在这里面

浏览器解析渲染页面

  • 这个图就是Webkit解析渲染页面的过程。解析HTML形成DOM树
  • 解析CSS形成CSSOM 树
  • 合并DOM树和CSSOM树形成渲染树
  • 浏览器开始渲染并绘制页面 这个过程涉及两个比较重要的概念回流重绘,DOM结点都是以盒模型形式存在,需要浏览器去计算位置和宽度等,这个过程就是回流。等到页面的宽高,大小,颜色等属性确定下来后,浏览器开始绘制内容,这个过程叫做重绘。浏览器刚打开页面一定要经过这两个过程的,但是这个过程非常非常非常消耗性能,所以我们应该尽量减少页面的回流和重绘

性能优化之回流重绘

回流

当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

会导致回流的操作:

  • 页面首次渲染
  • 浏览器窗口大小发生改变
  • 元素尺寸或位置发生改变
  • 元素内容变化(文字数量或图片大小等等)
  • 元素字体大小变化
  • 添加或者删除可见的DOM元素
  • 激活CSS伪类(例如::hover)
  • 查询某些属性或调用某些方法

一些常用且会导致回流的属性和方法:

  • clientWidth、clientHeight、clientTop、clientLeft
  • offsetWidth、offsetHeight、offsetTop、offsetLeft
  • scrollWidth、scrollHeight、scrollTop、scrollLeft
  • scrollIntoView()、scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

重绘

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

优化

CSS

  • 避免使用table布局。
  • 尽可能在DOM树的最末端改变class。
  • 避免设置多层内联样式。
  • 将动画效果应用到position属性为absolute或fixed的元素上。
  • 避免使用CSS表达式(例如:calc())。

JavaScript

  • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
  • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

.html & js & css

1.AMD和CMD是什么?它们的区别有哪些?

AMD和CMD是二种模块定义规范。现在都使用模块化编程,AMD,异步模块定义;CMD,通用模块定义。AMD依赖前置,CMD依赖就近。CMD的API职责单一,没有全局require,AMD的一个API可以多用。

2.web开发常见的漏洞。

XSS(跨站脚本攻击):其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户Cookie、破坏页面结构、重定向到其它网站等。

SQL注入:用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。

3.cookie和session

当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择,

都纪录下来。当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie 资料,有的话,就会依据 Cookie

里的内容来判断使用者,送出特定的网页内容给你。

当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id

4.MVC BFC

mvc是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。MVC对应Html,CSS,js。

BFC全称”Block Formatting Context”, 中文为“块级格式化上下文”。流体特性:块状水平元素,如div元素(下同),在默认情况下(非浮动、绝对定位等),水平方向会自动填满外部的容器;BFC元素特性表现原则就是,内部子元素不会影响外部的元素。

5.HTTP状态码:

 1.消息 2.成功 3.重定向 4.请求错误 5.服务器错误 304:响应禁止包含消息体,如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。 305:被请求的资源必须通过指定的代理才能被访问。 400:语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求,或者请求参数有误。 403:服务器已经理解请求,但是拒绝执行它。 404:请求失败,请求所希望得到的资源未被在服务器上发现。 500:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。

6.HTML 5 增加了一项新功能是 自定义数据属性 ,也就是 data- 自定义属性。在HTML5中我们可以使用以 data- 为前缀来设置我们需要的自定义属性,来进行一些数据的存放。

<div id = "user" data-uid = "12345" data-uname = "愚人码头" > </div>
// 使用getAttribute获取 data- 属性
var user = document . getElementById ( 'user' ) ;
var userName =user . getAttribute ( 'data-uname' ) ; // userName = '愚人码头'
var userId = user . getAttribute ( 'data-uid' ) ; // userId = '12345'

使用setAttribute设置 data- 属性

user . setAttribute ( 'data-site' , 'http://www.css88.com' ) ;

7.使div水平垂直都居中

知道DIV的自身长度和宽度,其实解决的思路是这样的:首们需要position:absolute;绝对定位。而层的定位点,使用外补丁margin负值的方法。负值的大小为层自身宽度高度除以二。[style="position: absolute;top:50%;left: 50%"]只能实现DIV离左边框和上边框的距离为屏幕的物理尺寸的一半,忽略了DIV本身的长度和宽度,所以不会实现DIV的水平垂直居中。

不知道DIV的本身长度和宽度时:

$(window).load(function(){
 $(".mydiv").css({position: "absolute", left: ($(window).width() - 
 $(".mydiv").width())/2, top: ($(window).height() - $(".mydiv").height())/2
 });
 });

8.Call()和apply()

构造函数:

function showname(){ 
 this.name="zygg";
}
var qq=new showname();
console.log(qq.name);

我们发现apply()和call()的真正用武之地是能够扩充函数赖以运行的作用域,可以改变函数体内部 this 的指向:

 window.firstName = "diz";
 window.lastName = "song"; 
 var myname = { firstName: "my", lastName: "Object" }; 
 function show() { 
 console.log("Hello " + this.firstName + " " +this.lastName, " glad to meet you!");
 }
 show();
 show.call(myname);//如果不这样写,对象myname是没法调用函数 show()的。

二者作用类似,区别就是参数不同:

call(thisObj,Object)

apply(thisObj,[argArray])

9.动态节点绑定事件

Live() 
delegate() 
bind()【处理文档中的静态部分,不用于。。。】

delegate()和live()作用类似,附加的事件处理程序适用于匹配选择器的当前及未来的元素(比如由脚本创建的新元素)。但二者参数不一样。

$(selector).delegate(childSelector,event,function)

$(selector).live(event,function)

$("div").delegate("p","click",function(){
 $(this).slideToggle();
});//只有DIV内的p元素会被绑定事件。

$("p").live("click",function(){
 $(this).slideToggle();
});//文档内所有p元素都会被绑定事件

bind()可以向元素添加的一个或多个事件处理程序,以及当事件发生时运行的函数。
$(selector).bind(event,function)

$("button").bind("click",function(){
 $("p").slideToggle();
});//bind【捆绑】

10.Position的四个属性详解

Position的四个属性:static,fixed,absolute,relative

首先,static,是position属性的默认值,也就是无特殊定位,遵循html定位规则。

然后,fixed,是相对于浏览器窗口进行定位,不随页面的上下翻动而移动,比如固定在页面末端的二维码等。

下来,就是absolute,它是相对于它的第一个父元素进行定位,如果你想让这个div#demo里的一个子div#sub相对于#demo定位在右上角的某个地方,应该给#demo相对定位,#sub绝对定位。 此时,它的第一个父元素就是id=demo的div;否则它的父元素就是body,这样它的位置在页面中保持不变,但是随着页面移动会发生变化(区别fixed)。

最后,relative,relative是相对于自己来定位的,相对于其正常位置进行定位。例如:#demo{position:relative;top:-50px;},这时#demo会在相对于它原来的位置上移50px。

P.S:采用左列left浮动,右列不浮动,采用margin-left定位的方式。

11.理解CSS盒子模型

什么是CSS的盒子模式呢?为什么叫它是盒子?先说说我们在网页设计中常听的属性名:内容(content)、填充(padding)、边框(border)、边界(margin), CSS盒子模式都具备这些属性。

CSS盒子模式

这些属性我们可以把它转移到我们日常生活中的盒子(箱子)上来理解,日常生活中所见的盒子也具有这些属性,所以叫它盒子模式。那么内容就是盒子里装的东西;而填充就是怕盒子里装的东西(贵重的)损坏而添加的泡沫或者其它抗震的辅料;边框就是盒子本身了;至于边界则说明盒子摆放的时候的不能全部堆在一起,要留一定空隙保持通风,同时也为了方便取出嘛。在网页设计上,内容常指文字、图片等元素,但是也可以是小盒子(DIV嵌套),与现实生活中盒子不同的是,现实生活中的东西一般不能大于盒子,否则盒子会被撑坏的,而CSS盒子具有弹性,里面的东西大过盒子本身最多把它撑大,但它不会损坏的。而且填充只有宽度属性。

12.区别onmouseover和mouseover

onmouseover是Event 对象的一个属性,Mouseover是jQuery中的一个事件 。

推荐使用jQuery,直接执行方法$("#id").mouseover(function(){});

完全使用js则是如下写法:document.getElementById("id").onmouseover=function(){};

document.getElementsByTagName("body")[0].style.backgroundColor="pink”; //注意不要忘了style,深刻理解DOM的本质。

13.一个简单的AJAX 的请求

<script type="text/javascript">
function loadXMLDoc(){
 var xmlhttp;
 if (window.XMLHttpRequest){
 // code for IE7+, Firefox, Chrome, Opera, Safari
 xmlhttp=new XMLHttpRequest();
 }else{
 // code for IE6, IE5
 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange=function() { 
 if (xmlhttp.readyState==4 && xmlhttp.status==200){ document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
 }
 }
 xmlhttp.open("GET","/ajax/demo_get.asp",true);
 xmlhttp.send();
 }
</script>

14.Javascript 的addEventListener()及attachEvent()区别分析

addEventListener()和attachEvent()是一个侦听事件并处理相应的函数,

可以动态的为网页内的元素添加一个或多个事件。可以将事件和元素分离,这样可编辑性就高了。

addEventListener的使用方式:

target.addEventListener(type, listener, useCapture);

target: 文档节点、document、window 或 XMLHttpRequest。

type: 字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。

listener :实现了 EventListener 接口或者是 JavaScript 中的函数。

useCapture :是否使用捕捉,一般用 false 。例如:document.getElementById("testText").addEventListener("keydown", function (event) { alert(event.keyCode); }, false);

而attachEvent()则是,target.attachEvent(type, listener);

注意:attachEvent()中的type: 字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。

15.关于事件监听

 比如,<button onclick='A();' /> 就表示"你正在监听 click 事件", 而事件监听器就是我们为了要响应这个事件而写的函数。至于事件监听机制了,就是冒泡和捕获。

16.事件监听机制(冒泡和捕获)

事件捕获:事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。

事件冒泡:事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签。

假设一个元素div,它有一个下级元素p。

<div>
 <p>元素</p>
</div>

这两个元素都绑定了click事件,如果用户点击了p,它在div和p上都触发了click事件,那这两个事件处理程序哪个先执行呢?

如div先触发,这就叫做事件捕获。

如p先触发,这就叫做事件冒泡。

IE只支持事件冒泡,其他主流浏览器两种都支持。

程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。

事件的传播是可以阻止的:

• 在W3c中,使用stopPropagation()方法

在捕获的过程中stopPropagation();后,后面的冒泡过程也不会发生了~

propagation 【传播,蔓延】

阻止事件的默认行为,例如click a标签后的跳转~

• 在W3c中,使用preventDefault()方法;

• 在IE下设置window.event.returnValue = false;

17.DNS的工作原理(递归和迭代)(应用层)

DNS的工作原理及过程分下面几个步骤:

第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。

第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。

第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域) 的主域名服务器的地址。

第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。

第五步:重复第四步,直到找到正确的纪录。

第六步:本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机。

18.什么是DOM事件处理程序?

首先要理解什么是DOM?Dom是针对HTML文档的一个API。什么是事件流?事件流分为:事件冒泡(IE的事件流)和事件捕获。事件冒泡就是由最具体的元素开始接收,然后逐级向上;事件捕获就是由不太具体的元素开始接收,逐级向下,最具体的元素最后才接收到事件。

DOM事件处理程序分为DOM0级、DOM2级。DOM0级具有简单,跨浏览器的优势,它是把函数赋值给一个事件的处理程序属性。例如:btn.onlick=function(){。。。};DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作。addEventListener()和removeEventListener()。它们都接收三个参数,要处理的事件名、作为事件处理程序的函数和布尔值。布尔值为true表示在捕获阶段调用事件处理程序,布尔值为false是在冒泡处调用。注意:事件名要去掉“on”。通过addEventListener()添加的事件,只能由removeEventListener()删除。IE存在兼容问题,可以用attachEvent()添加事件和detachEvent()删除事件。接收两个参数,事件处理程序的名称和函数。注意:事件名此时要加”on”。

19.如果给一个元素同时绑定两个事件,会怎么样?

Dom 0级和Dom 2级都可以给一个元素添加多个事件,Dom 0级的每个事件只支持一个事件处理程序,如果绑定同一个事件,那么后边的那个事件,函数会覆盖掉前边的那个事件函数。Dom2级可以添加多个事件处理程序,他们会按照添加的顺序触发。

20.深入理解闭包

要理解闭包,首先必须理解Javascript特殊的变量作用域。我的理解是,闭包就是能够读取其他函数内部变量的函数。

既然函数b可以读取函数a中的局部变量,那么只要把b作为返回值,我们不就可以在a外部读取它的内部变量了吗!

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

21.jQuery源码分析:

选择器 Sizzle引擎 回调对象 - Callbacks 事件绑定 - 绑定设计

DOM操作方法与核心 Ajax - 整体结构

选择器 Sizzle引擎:个人认为,sizzle选择器是增强版的querySelectorAll 函数:返回指定元素节点的子树中匹配selector的节点集合,采用的是深度优先预查找;如果没有匹配的,这个方法返回空集合)

22.设计模式:

一共有23种设计模式

1.观察者模式

2.监听模式

  1. Factory Method(工厂方法):定义一个用于创建对象的接口,让子类决定实例化哪一个类。就行构造函数
  2. Abstract Factory(抽象工厂):。。。
  3. Prototype(原型):当要实例化的类是在运行时刻指定时,例如,通过动态装载。

23.CSS框架:

YUI、JQuery、Prototype,bootstrap。

24.几个前端框架的区别:

jQuery

核心js只有50K,小而精,占用带宽小,侧重于对js dom编程。有灵活便捷的Ajax请求和回调操作。

ExtJS

一整套带有UI的js库,封装得很多,核心js就600多K,这么大的东西门户网站当然就别想了,里面的效果当然也不会运用到门户网站,所以它是专门为管理系统而生的。

3、YUI

或者是类似于网盘应用这种东东。

4.Dojo

Dojo是功能最为强大的javascript框架,刻意提醒一下:功能最强大。所以它几乎包含了所有你可能想要用到的东西。)。 Dojo更适合企业应用和产品开发的需要,

5、Prototype

最成熟的。但个人认为可以被Jquery取代。两者相似度也比较高。

25.说说float和position

float:none|left|right|inherit

Inherit:规定应该从父元素继承 float 属性的值。

float是相对定位的,会随着浏览器的大小和分辨率的变化而改变,而position就不行了,所以一般情况下还是float布局!在局部可能会用到position进行定位!既然是布局,就用float好,这个我比较常用。这个浮动是可以清除的,一般不会影响整体布局。 而position,定位,是不受约束的,这个貌似都谈不上布局了,一般要是做什么特殊的定位或者浮动层的时候,可以考虑使用!float会影响后面的元素,而position不会影响后面的元素。

26.清除浮动:

父级div定义 height,父级div手动定义height,就解决了父级div无法自动获取到高度的问题。

结尾处加空div标签 clear:both

父级div定义 overflow:hidden /auto

27.前端性能优化

①对于页面来说:尽量减少DOM元素的数量。

减少iframe的数量

减少http的请求次数

提前加载

②对于CSS来说:将样式表置顶

使用link代替@important

区别1:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。

区别2:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。link支持定义RSS(简易信息聚合).

区别3:link支持使用Javascript控制DOM去改变样式;而@import不支持。

③对于JS来说: 将脚本置底

使用外部JS和CSS文件 ,精简JS和CSS文件,去除重复脚本

目前,前端性能测试的执行工具也有很多,比如YSlow,Page Speed,dynaTrace AJAX Edition,webload等等。

28.HTML语义化

就是当你写html时,要按照人们的思考逻辑写。不但要自己能看懂,也要让别人也能看懂,不要让别人觉得你的代码很乱。语义化的主要目的就是让大家直观的认识标签(markup)和属性(attribute)的用途和作用。

语义化的网页的好处,最主要的就是对搜索引擎友好,有了良好的结构和语义你的网页内容自然容易被搜索引擎抓取,你网站的推广便可以省下不少的功夫。

语义 Web 技术有助于利用基于开放标准的技术,从数据、文档内容或应用代码中分离出意义。

29.可以谈谈自己对SEO和title和keywords堆砌问题。

30.说说jsonp,getJSON(),getScript():

Jsonp(解决跨域)

一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

因为,<script> 元素的这个开放策略。

getJSON():

所以getJSON和ajax的方式(实际就是jsonp)想比较,也就是callback函数一个是自动生成的函数名,一个是手工指定的函数名。

getScript():

客户端:

<script type="text/javascript">
 jQuery.getScript("http://alloyteamzygg.sinaapp.com/js/test.js",
 function(){
 console.log(zy.name)
 })
 </script>

服务端:

 Var zy={“name”:”zygg”,
“age”:”22”
};

31.prototype属性

每一个构造函数都有一个属性叫做原型(prototype)。这个属性非常有用:为一个特定类声明通用的变量或者函数。prototype是一个对象,因此,你能够给它添加属性。你添加给prototype的属性将会成为使用这个构造函数创建的对象的通用属性。

32.js实现类:

构造函数方式:

由于js类的定义方法和函数的定义方法一样,所以定义构造函数的同时就定义了类。构造函数内的方法和属性也就是类中的方法和属性。

原型方式

该方式利用了对象的prototype属性。首先定义了一个空函数,然后通过prototype属性来定义对象的属性。调用该函数时,原型的所有属性都会立即赋予要创建的对象

33.js面向对象

面向对象的语言有一个标志,即拥有类的概念

34.构造函数

js创建对象的方式包括两种:对象字面量和使用new表达式。对应代码:

Var zy={
 “name”:”zygg”,
 “age”:22} function zy(name,age){ this.name=name; this.age=age;
 }
 zy.prototype.sex="male"; var zygg=new zy("bailu",18) console.log(zygg.name) //bailu

35.js继承

继承是指一个对象直接使用另一对象的属性和方法

实现方法:

对象冒充,及call()Apply()参见上述call和apply的用法。

原型链方式:

js中每个对象均有一个隐藏的__proto__属性,一个实例化对象的__proto__属性指向其类的prototype方法,而这个prototype方法又可以被赋值成另一个实例化对象,这个对象的__proto__又需要指向其类,由此形成一条链。

那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。

36.js事件委托

“事件处理程序过多”问题的解决方案就是事件委托。

事件委托利用的是事件冒泡机制,只制定一事件处理程序,就可以管理某一类型的所有事件(使用事件委托,只需在DOM树中尽量最高的层次上添加一个事件处理程序)。

这里要用到事件源:event 对象,需要用到target属性,其 事件属性可返回事件的目标节点(触发该事件的节点)

dom.onmouseover = function(ev){ 
 var target = ev.target 
 if(target.nodeName.toLowerCase() == "li"){
 target.style.background = "red";
 }
}

37.js自定义事件:

js自定义事件用处较多,最主要的就是实现观察者模式.

观察者模式( 又叫发布者-订阅者模式 )应该是最常用的设计模式之一。

平时接触的dom事件. 也是js和dom之间实现的一种观察者模式.

观察者模式举例:

div.onclick = function click (){
 alert ( ''click' )
}

只要订阅了div的click事件. 当点击div的时候, function click就会被触发.Div为发布者,click事件为订阅者

自定义事件例子:

<script src="Scripts/jquery-2.1.1.min.js"></script>
 <script type="text/javascript">
 $(function() {
 $('body').on('someclick', function () {
 console.log('被点击了~~');
 });
 $('body').trigger('someclick');
 }); 
</script>

on()是jQuery中的类似于bind(),live(),delegate()等绑定事件的方法。

trigger() 方法触发被选元素的指定事件类型。先给固定元素绑定一个自定义事件”someclick”,然后必须通过trigger()来使自定义事件可以使用。

Trigger【引发,触发;】

38.回调函数:

函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。函数b是你以参数形式传给函数a的,那么函数b就叫回调函数。回调函数可以继续扩展一个函数的功能,可以是程序非常灵活。

 function zy(callback){
 alert("开始"); 
 callback();
 } 
 function zygg(){
 alert("我是回调函数");
 } 
 function test(){
 zy(zygg)
 }

39.说一说css中box和flex

恩恩,首先'box'呐是比较早的语法,使用它时需要带上前缀,比如 display: -webkit-box; / Chrome 4+, Safari 3.1, iOS Safari 3.2+ /,而"flex"是2012年的语法,是css3新规定的,也将是以后标准的语法。将父元素的display属性设置为-webkit-box(box),然后子元素通过属性-webkit-box-flex来指定一个框的子元素是否是灵活的或固定的大小,如上,定义两个灵活的p元素。如果父级box的总宽度为300px,#P1将有一个100px的宽度,#P2将有一个200px的宽度,也就是呈固定比例划分。当然了,也可以这样写:

<div style="background-color: pink;width: 500px;height:500px;display:flex">
 <p style="background-color: orange;
flex:1.0;border:1px solid red;">111111111111</p>
 <p style="background-color: orangered;
flex:2.0;border:1px solid blue;">22222222222</p></div

当然了css3规定了,一系列的有关box的属性,比如 box-shadow。。。。。

40.JavaScript内置对象有以下几种。

 String对象:处理所有的字符串操作 Math对象:处理所有的数学运算 Date对象:处理日期和时间的存储、转化和表达 Array对象:提供一个数组的模型、存储大量有序的数据 
 Event对象:提供JavaScript事件的各种处理信息 

41.JavaScript内置函数

①:escape( )escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。 eg:?=%3

②:eval( ) eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

eg:eval("x=10;y=20;document.write(x*y)")

③:isFinite( )isFinite() 函数用于检查其参数是否是无穷大。返回true或者false。

④:isNaN( ) isNaN( ) 函数可用于判断其参数是否是 NaN

⑤:parseFloat( )parseFloat() 函数可解析一个字符串,并返回一个浮点数。

⑥;parseInt( ) parseInt() 函数可解析一个字符串,并返回一个整数。

⑦:unescape( ) unescape() 函数可对通过 escape() 编码的字符串进行解码。

42.自适应问题

自适应指的就是指其长(宽)度可以根据浏器窗口的大小自动改变其长(宽)度(随浏览器长(宽)的改变而改变),而不会被浏览器遮住。

实现方法(以左侧固定,右侧自适应为例):

①采用左列 left 浮动,右列不浮动,采用 margin-left 定位的方式。

②左列使用绝对定位,右列使用 margin-left 定位。

43.我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,你来说下会执行几次事件,然后会先执行冒泡还是捕获!!!

44.jQuery的三种绑定事件方式:bind(),live(),delegate()

45.从输入 URL 到页面加载完的过程中都发生了什么事情?

①首先如果我们如果输入的不是ip地址,而是域名的话,就需要IP解析,DNS域名解析(具体见DNS工作机制)。

②解析出来对应的IP后,如不包含端口号,http协议默认端口号是80;https(http+ssl(传输层))是430!然后向IP发起网络连接,根据http协议要求,组织一个请求的数据包,里面包含大量请求信息。

③服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等。

④开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。

⑤将渲染好的页面图像显示出来,并开始响应用户的操作。

46.jQuery 选择器种类

47.Unicode和ASCII的区别是什么回答

计算机发明后,为了在计算机中表示字符,人们制定了一种编码,叫ASCII码。

中国人利用连续2个扩展ASCII码的扩展区域(0xA0以后)来表示一个汉字,该方法的标准叫GB-2312。因为各个国家地区定义的字符集有交集,因此使用GB-2312的软件,就不能在BIG-5的环境下运行(显示乱码),反之亦然。

为了把全世界人民所有的所有的文字符号都统一进行编码,于是制定了UNICODE标准字符集。UNICODE 使用2个字节表示一个字符(unsigned shor int、WCHAR、_wchar_t、OLECHAR)。

48.JS的数据类型:字符串、数字、布尔、数组、对象、Null、Undefined

Null和undefined的区别:

undefined表示变量声明但未初始化时的值,javascript解释器不知道这是什麽东西,会抛出"未定义"的错误

null表示准备用来保存对象,还没有真正保存对象的值。从逻辑角度看,null值表示一个空对象指针,意思是你定义了它,但它没有分配内存空间。

二.CSS(3)

css3总的说来大概就是边框的一些特殊样式,比如圆角,还有就是渐变,动画。

在CSS3中border-radius属性被用于创建圆角(前提是有边框属性):border-radius:10px;

 如果你在 border-radius 属性中只指定一个值,那么将生成 4 个 圆角。
 其也可以这样写:border-radius:1px 2px 3px 4px [可以给四个角同时设置]
 也可以border-top/bottom-left/right-radius,给某个角给值。
 其值也可以这样: border-radius: 15px/50px; border-radius: 50% ;【椭圆效果】

CSS3中的box-shadow属性被用来添加阴影:box-shadow : 3px 3px 3px yellow;[上右下左]

有了CSS3的border-image属性,你可以使用图像创建一个边框:

 -webkit-border-image : url(border.png) 30 30 round;

round : 图像平铺(重复)来填充该区域。

Stretch 这里,图像被拉伸以填充该区域。

background-size指定背景图像的大小。CSS3以前,背景图像大小由图像的实际大小决定。

background-size:80px 60px;

background-Origin属性指定了背景图像的位置区域。

content-box, padding-box,和 border-box区域内可以放置背景图像。

background-origin:border-box;

CSS3 允许你在元素,那个添加多个背景图像。

background-image:url(img_flwr.gif),url(img_tree.gif);

CSS3 background-clip 属性,类比background-origin[背景图片]

作用:指定绘图区的背景,也就是规定背景的真正作用区域。

语法:

background-clip: border-box|padding-box|content-box;

CSS3 定义了两种类型的渐变(gradients):

线性渐变(Linear Gradients)- 向下/向上/向左/向右/对角方向

径向渐变(Radial Gradients)- 由它们的中心定义

语法:background: -webkit-linear-gradient(red, pink); 从上到下

background: -webkit-linear-gradient(left, red , blue); 从左向右

-moz代表firefox浏览器私有属性

-ms代表IE浏览器私有属性

-webkit代表chrome、safari(苹果浏览器)私有属性

-o代表opera(欧朋浏览器)的私有属性

background: -webkit-linear-gradient(left top, red , blue); 渐变呈对角线变化,从左上角开始。

渐变的方向上也可以做更多的控制,您可以定义一个角度,而不用预定义方向:

background: -webkit-linear-gradient(180deg, red, blue);

也可以同时使用多个颜色节点:

background: -webkit-linear-gradient(red, green, blue);

CSS3 渐变也支持透明度(transparency),可用于创建减弱变淡的效果:

background: -webkit-linear-gradient(left, rgba(255,0,0,0), rgba(255,0,0,1));

我们使用 rgba() 函数来定义颜色结点。rgba() 函数中的最后一个参数可以是从 0 到 1 的值,它定义了颜色的透明度:0 表示完全透明,1 表示完全不透明。r代表红色,g代表绿色,b代表蓝色,a代表透明度。

重复的渐变:

background: -webkit-repeating-linear-gradient(...);

为了创建一个径向渐变,您也必须至少定义两种颜色结点。

background: -webkit-radial-gradient(red 5%, green 15%, blue 60%);

比例越大,”半径越大”,它的默认形状是椭圆。也可以自定义形状;

background: -webkit-radial-gradient(circle, red, yellow, green);

CSS3的文本阴影:

text-shadow: 5px 5px 5px #FF0000;分别对应水平阴影,垂直阴影,模糊的距离,以及阴影的颜色.

CSS3文本的强制换行:

p {word-wrap:break-word;}

CSS3 @font-face 规则,自定义字体。

<style> @font-face{font-family: myFirstFont;src: url('Sansation_Light.ttf')
 }div{font-family:myFirstFont;
}</style>

CSS3 2D 转换:

您将了解2D变换方法:

translate()

rotate()

scale()

skew()

matrix()

rotate()方法,在一个给定度数顺时针旋转的元素。负值是允许的,这样是元素逆时针旋转。

-webkit-transform:rotate(30deg); /* Safari and Chrome */ 注意是-webkit-transform :是冒号

translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动:

-webkit-transform:translate(50px,100px)

scale()方法,该元素增加或减少的大小,取决于宽度(X轴)和高度(Y轴)的参数

-webkit-transform:scale(1,2); 也就是宽度和高度呈对应的倍数增加。

skew()方法,该元素会根据横向(X轴)和垂直(Y轴)线参数给定角度:

skew(30deg,20deg)是绕X轴和Y轴周围20度30度的元素。

matrix 方法有六个参数,包含旋转,缩放,移动(平移)和倾斜功能。

rty 描述 CSS

transform 适用于2D或3D转换的元素 3

transform-origin 允许您更改转化元素位置 3

函数 描述

matrix(n,n,n,n,n,n) 定义 2D 转换,使用六个值的矩阵。

translate(x,y) 定义 2D 转换,沿着 X 和 Y 轴移动元素。

translateX(n) 定义 2D 转换,沿着 X 轴移动元素。

translateY(n) 定义 2D 转换,沿着 Y 轴移动元素。

scale(x,y) 定义 2D 缩放转换,改变元素的宽度和高度。

scaleX(n) 定义 2D 缩放转换,改变元素的宽度。

scaleY(n) 定义 2D 缩放转换,改变元素的高度。

rotate(angle) 定义 2D 旋转,在参数中规定角度。

skew(x-angle,y-angle) 定义 2D 倾斜转换,沿着 X 和 Y 轴。

skewX(angle) 定义 2D 倾斜转换,沿着 X 轴。

skewY(angle) 定义 2D 倾斜转换,沿着 Y 轴。

CSS3 3D 转换:

rotateX()

rotateY()

-webkit-transform:rotateX/Y(120deg); / Safari and Chrome /

CSS3 过渡 : transition 属性.

CSS3 过渡是元素从一种样式逐渐改变为另一种的效果。

要实现这一点,必须规定两项内容:

指定要添加效果的CSS属性

指定效果的持续时间

-webkit-transition: -webkit-transform 3s;

-webkit-transition-delay 规定过渡效果何时开始。默认是 0。

CSS3 动画

当在@keyframe创建动画,把它绑定到一个选择器,否则动画不会有任何效果。

指定至少这两个CSS3的动画属性绑定向一个选择器:

规定动画的名称

规定动画的时长

<style>
div{
width:100px;
height:100px;
background:red;
-webkit-animation:myfirst 5s; / Safari and Chrome /
}
@-webkit-keyframes myfirst / Safari and Chrome /
{
from {background:red;}
to {background:yellow;}
}
</style>
也可以这样写:
@-webkit-keyframes myfirst / Safari and Chrome /
{
0% {background:red;}
25% {background:yellow;}
50% {background:blue;}
100% {background:green;}
}

其中不仅仅跟background属性,可以跟一系列属性。

属性 描述 CSS

@keyframes 规定动画。 3

animation 所有动画属性的简写属性,除了 animation-play-state 属性。 3

animation-name 规定 @keyframes 动画的名称。 3

animation-duration 规定动画完成一个周期所花费的秒或毫秒。默认是 0。 3

animation-timing-function 规定动画的速度曲线。默认是 "ease"。 3

animation-delay 规定动画何时开始。默认是 0。 3

animation-iteration-count 规定动画被播放的次数。默认是 1。 3

animation-direction 规定动画是否在下一周期逆向地播放。默认是 "normal"。 3

animation-play-state 规定动画是否正在运行或暂停。默认是 "running"。 3

通过 CSS3多列,您能够创建多个列来对文本进行布局 - 就像报纸那样!

在本章中,您将学习如下多列属性:

column-count

column-gap

column-rule

div{
-webkit-column-count:3; /* Safari and Chrome */ 将文章划为3列
-webkit-column-gap:40px; /* Safari and Chrome */ 每列间的距离为40px
-webkit-column-rule:3px outset #ff00ff; /* Safari and Chrome */ 设置列之间
的宽度,样式和颜色
} 

三.Html5

Html5新加了一些语义元素,画布,拖放,web存储(localstarge,sessionstrage)等。

1.HTML5 定了 8 个新的 HTML 语义(semantic) 元素。所有这些元素都是 块级 元素。

为了能让旧版本的浏览器正确显示这些元素,你可以设置 CSS 的 display 属性值为 block:

2.你可以为 HTML 添加新的元素。

fuck{
Font-family:simhei;
Color:pink
}

本例中,JavaScript 语句 document.createElement("myHero") 是为了为 IE 浏览器添加新的元素。Internet Explorer 8 及更早 IE 版本的浏览器不支持以上的方式。幸运的是, Sjoerd Visscher 创建了 "HTML5 Enabling JavaScript", " shiv":以上代码是一个注释,作用是在 IE 浏览器的版本小于 IE9 时将读取 html5.js 文件,并解析它。

3.HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.

<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。Ie8以及以前不支持、

<script>var c=document.getElementById("myCanvas");var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);</script>

getContext() 方法返回一个用于在画布上绘图的环境。

设置fillStyle属性可以是CSS颜色,渐变,或图案。fillStyle 默认设置是#000000(黑色)。

fillRect(x,y,width,height) 方法定义了矩形当前的填充方式。

canvas 是一个二维网格。canvas 的左上角坐标为 (0,0)

在Canvas上画线,我们将使用以下两种方法:

moveTo(x,y) 定义线条开始坐标

lineTo(x,y) 定义线条结束坐标

然后使用 stroke() 方法来绘制线条:

在canvas中绘制圆形, 我们将使用以下方法: arc(x,y,r,start,stop)

ctx.arc(95,50,20,0,2*Math.PI);

参数分别为,圆心的横坐标,纵坐标,半径,起始角(以弧度记),结束角(以弧度记)

使用 canvas 绘制文本,重要的属性和方法如下:

font - 定义字体

fillText(text,x,y) - 在 canvas 上绘制实心的文本

strokeText(text,x,y) - 在 canvas 上绘制空心的文本

渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。

以下有两种不同的方式来设置Canvas渐变:

createLinearGradient(x,y,x1,y1) - 创建线条渐变

createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");// Create gradientvar grd=ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");// Fill with gradientctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);

将图片画在画布上:

var c=document.getElementById("myCanvas");var ctx=c.getContext("2d");var img=document.getElementById("scream");
ctx.drawImage(img,10,10);

SVG 指可伸缩矢量图形 (Scalable Vector Graphics)SVG 图像在放大或改变尺寸的情况下其图形质量不会有损失

Canvas 与 SVG 的比较:

SVG 是一种使用 XML 描述 2D 图形的语言。Canvas 通过 JavaScript 来绘制 2D 图形。

Svg支持事件处理器,canvas不支持事件处理器

在 SVG 中,每个被绘制的图形均被视为对象,而canvas能够以 .png 或 .jpg 格式保存结果图像

如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

Html5的拖放功能、

HTML5 - 使用地理定位:请使用 getCurrentPosition() 方法来获得用户的位置。

Html5新的input类型:

color
date
datetime
datetime-local
email
month
number
range
search
tel
time
url
Week

HTML5 新的表单元素:

<datalist>
<keygen>
<output>

Select和datalist的区别:

select:5个值里面选择1个;

datalist:你可以在文本框里填值,也可以在下面5个值里选1个。

<input list="browser" name="browser">
<datalist id="browser">
 <option value="Internet Explorer"></option>
 <option value="Firefox">
 <option value="Chrome">
 <option value="Opera">
 <option value="Safari">
</datalist>
<input type="submit">

<keygen> 元素的作用是提供一种验证用户的可靠方法。

<keygen>标签规定用于表单的密钥对生成器字段。

当提交表单时,会生成两个键,一个是私钥,一个公钥。

<output> 元素用于不同类型的输出,比如计算或脚本输出:

<form oninput="x.value=parseInt(a.value)+parseInt(b.value)">0
 <input type="range" id="a" value="50">100
 +<input type="number" id="b" value="50">
 =<output name="x" for="a b"></output>
</form>

属性 值 描述

for element_id 定义输出域相关的一个或多个元素。

form form_id 定义输入字段所属的一个或多个表单。

name name 定义对象的唯一名称。(表单提交时使用)

P.S:别忘了给range和number设置value属性。

<form>新属性:

autocomplete

novalidate

<input>新属性:

autocomplete

autofocus

form

formaction

formenctype

formmethod

formnovalidate

formtarget

height and width

list

min and max

multiple

pattern (regexp)

placeholder

required

step

①. autocomplete 属性规定 form 或 input 域应该拥有自动完成功能。

当用户在自动完成域中开始输入时,浏览器应该在该域中显示填写的选项。有on(开),off(关)。

②.novalidate 属性规定在提交表单时不验证 form 或 input 域输入元素的合法性。

③.autofocus 属性是一个 boolean 属性.autofocus 属性规定在页面加载时,域自动地获得焦点,就是进去就可以直接输入。

④.form 属性规定输入域所属的一个或多个表单。Eg:

<form action="demo-form.php" id="form1">

First name: <input type="text" name="fname">

<input type="submit" value="Submit">

</form>

Last name: <input type="text" name="lname" form="form1">

"Last name" 字段没有在form表单之内,但它也是form表单的一部分。

⑤The formaction 属性用于描述表单提交的URL地址.

⑥formenctype 属性描述了表单提交到服务器的数据编码 (只对form表单中 method="post" 表单)

⑦formmethod 属性定义了表单提交的方式。

⑧novalidate属性描述了 <input> 元素在表单提交时无需被验证。

⑨formtarget 属性指定一个名称或一个关键字来指明表单提交数据接收后的展示。

<input type="submit" formtarget="_blank" value="提交到一个新的页面上">

10.height 和 width 属性规定用于 image 类型的 <input> 标签的图像高度和宽度。

<input type="image" src="05.jpg">这种形式写在表单里,可以实现点击图片提交表单。

11.list 属性规定输入域的 datalist。datalist 是输入域的选项列表。结合datalist标签使用。

12.min、max 和 step 属性用于为包含数字或日期的 input 类型规定限定(约束)。

13. multiple 属性是一个 boolean 属性. multiple 属性规定<input> 元素中可选择多个值。例如同时选择多个文件上传。

14.pattern 属性描述了一个正则表达式用于验证 <input> 元素的值。

15.placeholder 属性提供一种提示(hint),描述输入域所期待的值

16.required 属性规定必须在提交之前填写输入域(不能为空)。

17.step 属性为输入域规定合法的数字间隔。

如果 step="3",则合法的数是 -3,0,3,6 等

语义元素:

一个语义元素能够清楚的描述其意义给浏览器和开发者。

无语义 元素实例: <div> 和 <span> - 无需考虑内容.

语义元素实例: <form>, <table>, and <img> - 清楚的定义了它的内容.

HTML5中新的语义元素:

许多现有网站都包含以下HTML代码: <div id="nav">, <div class="header">, 或者 <div id="footer">, 来指明导航链接, 头部, 以及尾部.

<section> 标签定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。

<article> 标签定义独立的内容。.

<nav> 标签定义导航链接的部分。

<aside> 标签定义页面主区域内容之外的内容(比如侧边栏)。

<header>元素描述了文档的头部区域

<footer> 元素描述了文档的底部区域.

<figure>标签规定独立的流内容(图像、图表、照片、代码等等)。

<figcaption> 标签定义 <figure> 元素的标题.

为了让这些块及元素在所有版本的浏览器中生效,你需要在样式表文件中设置一下属性 (以下样式代码可以让旧版本浏览器支持本章介绍的块级元素):

header, section, footer, aside, nav, article, figure
{ 
display: block; 
}

HTML5 Shiv解决ie旧版本不支持h5新元素。浏览器小于IE9版本时会加载html5shiv.js文件. 你必须将其放置于<head> 元素中。让CSS 样式应用在未知元素上只需执行 document.createElement(elementName) 即可实现。html5shiv就是根据这个原理创建的。如下:

<!--[ifltIE9]>
<script
type="text/javascript"
src="scripts/html5shiv.js"></script>
<![endif]-->

HTML5 Web 存储

早些时候,本地存储使用的是cookies。但是Web 存储需要更加的安全与快速.

localStorage - 没有时间限制的数据存储

sessionStorage - 针对一个 session 的数据存储

 if(typeof(Storage)!=="undefined")
 { if (localStorage.clickcount)
 { localStorage.clickcount=Number(localStorage.clickcount)+1;
 } else
 { localStorage.clickcount=1;
 }

HTML5 应用程序缓存

1.离线浏览 - 用户可在应用离线时使用它们

2.速度 - 已缓存资源加载得更快

3.减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源。

 <!DOCTYPE HTML><html manifest="demo.appcache">...</html>

manifest 文件需要配置正确的 MIME-type,即 "text/cache-manifest"。必须在 web 服务器上进行配置。manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。

manifest 文件可分为三个部分:

CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存

NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存

FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)

HTML5 Web Workers

web worker 是运行在后台的 JavaScript,不会影响页面的性能。

当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。

首先,检测浏览器是否支持web worker。
if(typeof(Worker)!=="undefined"){
 ......
}
 首先创建 web worker 文件,也就是外部的js文件 
 var i=0;
 postMessage(i);
 创建 Web Worker 对象
 w=new Worker("demo_workers.js");

当我们创建 web worker 对象后,它会继续监听消息(即使在外部脚本完成之后)直到其被终止为止。

w.terminate(); terminate【终止】

具体实例:

 if(typeof(Worker)!=="undefined"){ var w=new Worker("client.js");
 w.onmessage=function(ev){
 alert(ev.data)
 }
 }
 关键:postMessage() onmessage;

HTML5 服务器发送事件(Server-Sent Events):

Server-Sent 事件指的是网页自动获取来自服务器的更新。 单向消息传递.

客户端代码:

<!DOCTYPE html><html>
 <meta http-equiv="content-type" content="text/html charset=utf-8"><body><h1>获得服务器更新</h1><div id="result"></div><script>if(typeof(EventSource)!=="undefined")
 { var source=new EventSource("test.php");
 source.onmessage=function(event) { document.getElementById("result").innerHTML+=event.data+ "<br />";
 };
 }else
 { document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
 }</script></body></html>

服务器代码: