最近做项目在前端我使用了很多新技术,这些技术有bootstrap、angularjs,不过最让我兴奋的还是使用了HTML5的技术,今天我想总结一些HTML5的技术,好记性不如烂笔头,写写文章可以很好的整理思路,写到博客里还能做个备忘。

  1) 跨域通讯

  现在做企业项目,前端很不自然的会大量使用iframe标签,我以前在文章里提到iframe是一个效率极其低下的标签,但是如果项目没有什么性能的苛求,使用iframe还是非常的方便的。

  使用iframe经常碰到父子窗体通讯的问题,我们看看下面的代码:

  父页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父窗体</title>
</head>
<body>
<span id="superSpan">父窗体</span>&nbsp;&nbsp;<button onclick="pTest()">点击</button>
<iframe src="inner.html" width="300"></iframe>
</body>
</html>
<script type="text/javascript">
var superStr = "父窗体:hello iframe";
function pTest(){
var s = window.frames[0].window.subStr;
alert(s);
}
</script>

  子窗体页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子窗体</title>
</head>
<body>
<span id="subSpan">子窗体</span>&nbsp;&nbsp;<button onclick="sTest()">点击</button>
</body>
</html>
<script type="text/javascript">
var subStr = "子窗体:OK,Good!";
function sTest(){
var s = parent.superStr;
alert(s);
}
</script>

  由上面例子我们可以知道父子窗体可以进行信息的交流,不过这个交流局限性很高,它只能是做到javascript变量和方法的相互交流,如果我们想在父页面操作子页面的DOM结构或者子页面想操作父页面的DOM结构,这都是不行的(不过这点在我即将要说到的技术也是没法做到的),另外还有一个非常重要的一点那就是这些操作必须是同域下的。

  今天我介绍下HTML5里实现父子窗体通讯的解决方案,它不仅可以在同域下相互发送信息,在不同域名下也是可以相互发送信息的。

  同域名下的例子:

  父窗体:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5通讯API</title>
</head>
<body>
<h1>通讯示例,相同域名下</h1>
<iframe width="500" src="http://localhost:63342/socketprj/sub.html" onload="test()"></iframe>
<div id="showcontent"></div>
</body>
</html>
<script type="text/javascript">
window.addEventListener("message",function(evt){
document.getElementById("showcontent").innerHTML = evt.data;
},false); function test(){
var frm = window.frames[0];
frm.postMessage("你好,我是父页面访问地址是http://localhost:63342/socketprj/main.html","http://localhost:63342/socketprj/sub.html");
}
</script>

  子窗体:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子页面</title>
</head>
<body>
子页面
</body>
</html>
<script type="text/javascript">
window.addEventListener("message",function(evt){
console.log(evt);
document.body.innerHTML = "父页面过来的数据:" + evt.data;
evt.source.postMessage("子页面回传过来的信息地址是" + this.location + ",父页面的地址是" + evt.origin,evt.origin);
},false);
</script>

  这种跨域通讯方式其实就是一个事件,这个事件就是message事件,它是window对象下的一个事件,接收信息就是给window对象绑定message事件,event对象的data属性可以获取发送过来的信息,发送信息则是使用postMessage方法了。

  如果是跨域,子窗体的代码不变同上,父窗体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5通讯API</title>
</head>
<body>
<h1>通讯示例,不相同域名下</h1>
<iframe width="500" src="http://localhost:8080/sub.html" onload="test()"></iframe>
<div id="showcontent"></div>
</body>
</html>
<script type="text/javascript">
window.addEventListener("message",function(evt){
document.getElementById("showcontent").innerHTML = evt.data;
},false); function test(){
var frm = window.frames[0];
frm.postMessage("你好,我是父页面访问地址是http://localhost:63342/socketprj/main.html","http://localhost:8080/sub.html");
}
</script>

  2) 浏览器的多线程技术:web worker

  这里我们先看一个例子吧,这个例子是没有使用多线程技术做一个超长javascript运算,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>对比测试的参照页面worker</title>
</head>
<body>
<h1>对比测试的参照页面:javascript执行时间过长会导致浏览器终止javascript执行</h1>
请输入:<input type="text" id="ipt"/>&nbsp;&nbsp;<button onclick="test()">计算</button>
</body>
</html>
<script type="text/javascript">
function test(){
var num = parseInt(document.getElementById("ipt").value,10);
var res = 0;
for (var i = 0;i < num;i++){
res += 1;
}
alert(res);
}
</script>

  我们在页面里输入999999999999,等一段时间,浏览器会弹出一个提示框,如下图所示:

  浏览器会提示我们去终止javascript执行,这是为啥了?

  浏览器内部其实包含两个执行引擎,一个是渲染引擎,这个引擎负责页面的展示,一个是javascript引擎,它负责javascript执行,但是浏览器在实际执行的方式是以单线程的方式执行渲染操作和javascript操作,也就是说页面一回只能执行一个操作要么渲染页面要么就是执行javascript代码,因此当javascript执行时候就会阻塞渲染的执行,假如javascript执行时间过长页面加载就会被阻塞,这时候我们就会感觉页面不可用了,为了避免javascript过长执行导致页面无法使用,浏览器在检测到javascript执行到一个极限次数时候就会弹出以上提示框。

  关于浏览器能不能提供多线程的解决方案有人曾经咨询过javascript之父,这位大师很干脆的说,这是不可能的,他提出的理由是多线程操作过于复杂,那怕是最有经验的程序员也很难控制好多线程技术,引入它只会增加学习成本和开发风险。

  不过话说回来,传统的浏览器单线程改成多线程执行难度还是很大的,因为javascript是有权利修改页面的展示,如果引入多线程,搞不好程序员就很难正确控制页面的展示了。

  谷歌的工程师为了让浏览器有更好的用户体验,在HTML5没有出现之前做出了一个解决方案,那就是Gear,Gear其实就是web worker的前身,web worker相当于Gear的升级版,下面我们就来看看web worker的使用吧,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>worker单线程,无嵌套</title>
</head>
<body>
<h1>worker单线程,无嵌套</h1>
请输入:<input type="text" id="ipt"/>&nbsp;&nbsp;<button onclick="test()">计算</button>
</body>
</html>
<script type="text/javascript">
var worker = new Worker("js/worker.js");
worker.onmessage = function(evt){
alert(evt.data);
} function test(){
var num = parseInt(document.getElementById("ipt").value,10);
worker.postMessage(num);
}
</script>

  woker.js的代码如下:

onmessage = function(evt){
var num = evt.data;
var res = 0;
for (var i = 0;i < num;i++){
res += 1;
// console.log(res);
}
postMessage(res);
}

  使用worker技术,我们要把多线程的代码写在一个单独的js文件里面,同时定义一个onmessage方法,这个相当于一个事件的回调函数,回调函数的参数event里的data属性用来接收数据,postMessage方法传输数据,这个做法和前面的message相似。本例子只是演示了一个单线程的例子,我们还可以使用线程嵌套线程,这个我就不细说了,有兴趣的朋友可以尝试一下。

  3) 本地存储

  HTML5的web storage技术有两个一个是sessionstorage和localstorage,sessionstorage顾名思义就是只在会话有效,localstorage则是长时间有效,我在项目里做demo程序时候,就使用localstorage做本地存储,相当于一个小型数据库,web storage技术很简单,我就给一个简单例子,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>本地存储-存储数据</title>
</head>
<body>
<h1>本地存储-存储数据</h1>
</body>
</html>
<script type="text/javascript">
localStorage.setItem("mess","Hello Message!");
localStorage.setItem("obj",{id:"111",name:"xtq"});
</script>

  在chrome浏览器里我们可以在控制台里Resource的local Storage找到存储的数据,我们可以发现obj最终存储的是[object,object],这就说明web storage只能存储字符串,如果我们想存储javascript对象就的将其序列化变成字符串进行存储。

  4) 多文件上传

  文件上传使用的标签就是:

<input type="file" multiple id="fileIpt" size="120"/>

  在html4里,这个标签只能上传一个文件,现在我们只要在标签里加入multiple属性就可以实现多文件上传。在html4里ajax是没有办法做上传文件操作,因此我们如果想实现ajax文件上传就不得不使用hack技术,模拟文件上传,这个我曾在博客里分享过我写的模拟多文件上传的demo,当时也是没法子要保证浏览器兼容性,不得不hack一把了。

  在html5里我们对文件上传的控制力变得更强了,今天只展示一个简单文件上传操作的API,今后我会写一个复杂的多文件上传的demo和大家一起分享下,我们先看下面这个例子:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上传</title>
</head>
<body>
<input type="file" multiple id="fileIpt" size="120"/><br/>
<button onclick="test()">点击测试</button>
</body>
</html>
<script type="text/javascript">
function test(){
var f = document.getElementById("fileIpt");
var sFileList = "";
for (var i = 0;i < f.files.length;i++){
var item = f.files[i];
sFileList += "文件名称:" + item.name + "\n修改时间:" + item.lastModifiedDate + "\n文件大小:" + item.size + "\n文件类型:" + item.type + "\n=================\n";
}
alert(sFileList);
}
</script>

  在我做一个图片上传项目的时候,曾经有个想法就是想在图片客户端这里,也就是在文件传输到服务器之前给文件一个预览功能,当时我没时间仔细查阅资料,因此自己还是按照HTML4里掌握的知识认为浏览器在客户端是无法操作文件数据的,因此很难实现这个想法。最近看书发现原来HTML5已经可以做到这一点了,我写了一个例子和大家分享下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片本地显示</title>
</head>
<body>
<input type="file" multiple id="fileIpt" size="120"/><br/>
<button onclick="test()">显示图片</button>
<div id="result"></div>
</body>
</html>
<script type="text/javascript">
function test(){
var files = document.getElementById("fileIpt").files;
for (var i = 0;i < files.length;i++){
var f = files[i];
if (f.type.indexOf("image") != -1){
var reader = new FileReader();
reader.readAsDataURL(f);
reader.onload = function(evt){
var resDiv = document.getElementById("result");
var oImg = document.createElement("img");
oImg.setAttribute("src",this.result);
oImg.setAttribute("width",300);
oImg.setAttribute("height",300);
resDiv.appendChild(oImg);
} }
}
}
</script>

  好了,今天文章就写到这里,对于多文件上传我之后一定抽时间写个完整的例子出来,自己上次做项目对这块做的很是过瘾,而今天还发现了可以在客户端预览图片,因此这块很值得写个好demo了。

HTML5笔记:跨域通讯、多线程、本地存储和多图片上传技术的更多相关文章

  1. 学习web前端技术的笔记,仅供自己查阅备忘,图片上传预览

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  2. html5跨域通讯之postMessage的用法

    转自:http://www.cnblogs.com/wshiqtb/p/3171199.html postMessagePortal.html 页面代码 <!DOCTYPE html> & ...

  3. 使用HTML5 的跨域通信机制进行数据同步

    离线应用系统的设计目标就是在网络离线情况下依然可以操作我们的应用系统,并在网络畅通的情况下与服务器进行数据交互. 所以离线应用系统最终会做成类似C/S架构的客户端应用程序.这边基于Chrome或者 S ...

  4. (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage

    原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(2):本地存储之localStorage ...

  5. HTML5解决跨域问题

    HTML5解决跨域问题 由于浏览器的同源策略,网络连接的跨域访问是不被允许的,XHR对象不能直接与非同源的网站处理数据交互.而同源指的是什么呢?同源的范畴包括:规则(协议),主机号(域名.ip等),端 ...

  6. XDomainRequest IE8&amp;IE9 cors 跨域通讯的处理方法

       版权声明:避免百度一下通片同一篇文章,未经博主允许不得转载.本博客作为笔记使用,正确性请自行验证. https://blog.csdn.net/u014071104/article/detail ...

  7. (转)HTML5开发学习(3):本地存储之Web Sql Database

    原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(3):本地存储之Web Sql Data ...

  8. iframe跨域通讯

    工作中遇到一个问题,IFRAME嵌套了一个外部页面用于统计 统计的JS由我们提供,并且需要提供热点图 一开始就碰到的问题就是 不知道页面高度 需要子页面传回页面高度用于将IFRAME拉升到合适高度 当 ...

  9. spring mvc 图片上传,图片压缩、跨域解决、 按天生成文件夹 ,删除,限制为图片代码等相关配置

    spring mvc 图片上传,跨域解决 按天生成文件夹 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ ...

随机推荐

  1. 动画requestAnimationFrame

    前言 在研究canvas的2D pixi.js库的时候,其动画的刷新都用requestAnimationFrame替代了setTimeout 或 setInterval 但是jQuery中还是采用了s ...

  2. UITextView 输入字数限制

    本文介绍了UITextView对中英文还有iOS自带表情输入的字数限制,由于中文输入会有联想导致字数限制不准确所以苦恼好久,所以参考一些大神的博客终于搞定,欢迎大家参考和指正. 对于限制UITextV ...

  3. [C#] 简单的 Helper 封装 -- RandomHelper

    using System; namespace Wen.Helpers { /// <summary> /// 随机数助手 /// </summary> public seal ...

  4. 代码的坏味道(18)——依恋情结(Feature Envy)

    坏味道--依恋情结(Feature Envy) 特征 一个函数访问其它对象的数据比访问自己的数据更多. 问题原因 这种气味可能发生在字段移动到数据类之后.如果是这种情况,你可能想将数据类的操作移动到这 ...

  5. iOS微信第三方登录实现

    iOS微信第三方登录实现   一.接入微信第三方登录准备工作.移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统.在进行微信OAuth2.0授权登录接入之前,在微信开 ...

  6. 安卓客户端a标签长按弹框提示解决办法

    昨天工作时候发现一个bug,是关于a标签的,在安卓客户端中,如果是a标签的话,长按会出现一个弹框,如图所示 是因为安卓客户端的长按触发机制,以后进行wap端开发的时候,如果用到跳转页面尽量不要用a标签 ...

  7. Java实现FTP文件与文件夹的上传和下载

    Java实现FTP文件与文件夹的上传和下载 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制 ...

  8. sqlyog导出json数据格式支持mysql数据转存mongodb

    <!-------------知识的力量是无限的(当然肯定还有更简单的方法)-----------!> 当我考虑将省市区三级联动数据从mysql转入mongodb时遇到了网上无直接插入mo ...

  9. linux基础命令

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...

  10. 学习笔记 :DrawText

    最近在做一个TStringGrid的自绘处理,在画文字处理上遇到了高度的计算问题.后来经过一段时间还是找到了一些方法: 1.使用TLabel 这个方法是有点绕路的,方法倒是简单,就是使用AutoSiz ...