A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Conning 中级黑马   /  2014-5-12 20:51  /  2247 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

准备工作,我们先:
var http = {}; // 创建一个空对象
-----------------------------------------------


【1】preload 预加载资源



大家都知道,访问网页的时候,如果页面图片(或者其它资源) 过多,网页打开速度会变慢,那是因为浏览器在下载服务器端的资源。
此时,为了增强用户体验,可以在特殊场合,使用预加载,比如 你在做一款HTML写的小游戏,使用了较多的图片素材,这个时候它就可以派上用场了,先给用户来个百分比,加载到100%后,再开始游戏。


那到底是如何实现预加载的呢?其实很简单,如下:
-------------
var img = document.createElement('img');// 创建一个img元素
img.src = '图片地址';// 设置图片地址
-------------
当程序执行到 img.src = 这句的时候,浏览器将请求服务器 ,获取该图片。
等到我们真正游戏的时候,再用这个图片地址获取图片的时候,浏览器将直接从缓存中读入图片,而不是从服务器端获取,这样就达到了预加载的效果。为了程序得到图片什么时候加载完:
img.onload = function(){
// 图片加载完毕的回调函数
// 做某些事,比如显示:资源加载完成。
img = null; // 释放
}
-------------------


所以,整体代码大致如下:


// 预加载资源
http.preload = function(url, callback) {
var img = document.createElement('img');
img.src = url;
img.onload = function(){
typeof callback ==='function' && callback.call(this);
img = null;
}
}


10 个回复

倒序浏览
【2】动态引入CSS文件


有的时候,根据程序的需要,(比如判断当前浏览器大小或者浏览设备,加载不同的CSS文件),或者网页换皮肤的功能。


此时,我们就需要动态的加载CSS文件了
大致如下:
http.loadCss = function(url){
var link = document.createElement('link'); //创建一个link元素
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
document.getElementsByTagName('head')[0].appendChild(link); // 加到head标签内
}
(放在贴吧里,代码格式就乱了,排版不是很好)
-------------------
当CSS从服务器端加载完后,将自动应用新的样式,
回复 使用道具 举报
【3】动态引入JavaScript文件


和【2】类似,比如你要动态的 拿某个网站(或自己站点) 的JS,引入到自己的页面中使用。而你又不想一开始就加载,而是需要的时候再用。
--
http.loadJs = function(url) {
var script = document.createElement('script');//创建script标签
script.type = 'text/javascript';
script.src = url;
document.getElementsByTagName('body')[0].appendChild(script);//加入到body结束标签之前。
}
** 这里有一个知识点,把 script 标签放在 </body> 之前,而不是 <head> 中,可以提高页面的打开速度。这样CSS文件先加载,浏览器把样式都渲染好了,不影响用户浏览页面,而JS则会在页面加载完成后才开始加载。
回复 使用道具 举报
【4】跨域 GET 请求 ( jsonp )


楼主一般是直接使用 jQuery 的方法,但是今天心血来潮,打造自己的类,怎可用别人的库?


jsonp 的原理,是利用 script 标签可以动态加载并执行的特性,
在服务器端输出一段JS,来执行 JS的方法(); ,达到传递参数到前端的目的。
说的有点绕,这个要和服务器端配合,我们先了解流程和原理,再来封装,就简单的举个例子:
---
[前端]:
<script type="text/javascript">
function dzt(value){
alert(value);
}
</script>
<script type="text/javascript" src="http://localhost/jsonp.jsp"></script>
我们将 script 的 src 指向一个 jsp 文件
---
[后端]:
out.println("dzt('hello world')");
-----
就做一件事,输出 dzt('hello world'); 字符串。
此时你会发现,页面将弹出 hello world, 这就是 jsonp了, 很简单吧~?
------------------------
但是封装成通用的方法,我们不能一直用 吊炸天dzt() 这个function吧?jQuery采用的是 jquery + 时间戳的命名规则。


我们也模仿一下! jsonp + 时间戳
(另外,我的方法都没有做参数检查,异常什么的,这个我就不说了,只写关键代码)
------------------------
// url 请求地址
// data 请求的数据比如 { username: 'admin' , password: '123' } 对象格式
// callback 回调数据的函数(就类似上面的 dzt 函数 )
http.jsonp = function(url, data, callback) {
var callbackName = 'jsonp' + Date.now();// 生成时间戳命名的函数名
window[callbackName] = callback; // 这个很重要,就是把callback取一个随机名,然后放在window(全局)作用域上,以便等下可以调用到


// 把 对象格式 转成 a=1&b=2&c=3 的格式
var param = [];
for (var i in data) {
// encodeURIComponent 是中文URL编码
param.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
}
param.push('callback=' + callbackName); // 这句很重要,用来告诉后端,我们前端的回调函数名是什么。


// 和上面的动态加载js类似,只不过我们要加载完的回调函数,然后删除掉这个元素 和 回调函数,用以释放资源。


var script = document.createElement('script');
script.onload = script.onreadystatechange = function() {
this.parentNode.removeChild(this);
delete window[callbackName];
script.onload = script.onreadystatechange = null;
}
//请求数据 这里默认 url 不能加 问号, 你也可以做判断 没有问号就加上 ,有则不加。
script.src = url + '?' + param.join('&');
document.getElementsByTagName('body')[0].appendChild(script);


}
--
[后端]:


//拿到函数名
String callback = request.getParameter("callback");


// 查询数据库,并格式化为 json 字符串
String json = "{ result: true , status: '登录成功' }";


// 输出 callback( { 数据 } );
out.println( callback + "(" + json + ")" );


// 页面将调用 jsonp + 时间戳的那个函数,也就是我们的第三个数据回调的函数,
于是我们可以这样:
http.jsonp('http://localhost/jsonp.jsp', { username: 'admin' , password: '123' } . function(json){


alert( json.status ); // 弹出 登录成功


});
回复 使用道具 举报
【5】 同域 ajax 请求


jQuery 底层是先写了一个"超级复杂的函数": $.ajax();
然后再拿这个函数,封装出: $.get(); $.post(); 等等 一系列简化方法


我们不考虑太多,比如什么加载完毕后,成功后,失败后,执行什么回调。
-----------------------
// (方法GET或POST, 请求地址, 请求参数, 回调函数);
http.ajax = function(method, url, data, callback) {
// 拿到 XMLHttpRequest 对象
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); // 判断浏览器支持,ActiveXObject 为 IE 独有的。


xhr.open(method, url); // 打开连接


if (method === 'POST') { // 如果是 POST 请求,加上 请求头Content-Type字段
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}


xhr.onreadystatechange = function() { // 状态被改变事件
if (xhr.readyState === 4) { // 完毕
// 调用回调函数,并且把 responseText (就是 out.println 输出的内容) 用 eval('(' + responseText + ')'); 调用一次,eval 是动态编译执行JS脚本的方法,外面加个 ( ) 括号,就可以将后端输出的字符串,转为json对象。


typeof callback === 'function' && callback(eval('(' + xhr.responseText + ')'), xhr.status);
xhr = null;
}
}
xhr.send(data); // 发送数据
},

回复 使用道具 举报
【6】 GET ,POST (基于【5】的封装)


另外说一句,用的时候不要调用 http.ajax ,它还不能直接使用,只是用来作为我们 GET POST 方法的底层封装函数。


http.get = function(url, data, callback){
var param = [];
for (var i in data)
param.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
}
http.ajax('GET', url + '?' + param.json('&'), null, callback);
}
---------------------
http.post= function(url, data, callback){
var param = [];
for (var i in data)
param.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
}
http.ajax('POST', url, param.json('&'), callback);
}
---------------------
调用格式 和 http.jsonp 是一致的。
回复 使用道具 举报
【后话】


以上函数均未进行参数检查 和 规范。 作为一个健壮的工具类,需要有完善的参数检查,异常处理机制。


不能因为参数不对就报错了,就不好玩了~。


我会用到的就是这些了,欢迎补充,修正 ,我的演讲完了,谢谢大家。
回复 使用道具 举报
太难了,看不懂
回复 使用道具 举报
顶一下先
回复 使用道具 举报
好,实用技术
回复 使用道具 举报
好好好好好好好好好好好好好好好好好好好好好
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马