简单版
简单版的实现大致如下:
- var head = document.getElementsByTagName('head')[0];
- var script = document.createElement('script');
- /*onreadystatechange在IE下使用,onload在其他浏览器下使用*/
- script.onload = script.onreadystatechange = function(){
- if( !script.readyState || (script.readyState && script.readyState == 'loaded'){
- //TODO
- }
- }
- head.appendChild(script);
var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); /*onreadystatechange在IE下使用,onload在其他浏览器下使用*/ script.onload = script.onreadystatechange = function(){ if( !script.readyState || (script.readyState && script.readyState == 'loaded'){ //TODO } } head.appendChild(script);
短短几行代码已经能满足基本的需求了,而且兼容性还很不错。不过无法提供出错处理,而且使用起来不方便。
完整版
具体的说明都注释在代码中,请看注释。
IE
- function loadIECallback(param){
- param = initParam(param);
- /*清除,防止内存泄露*/
- function clear(){
- frag = script = script.onreadystatechange = frag[param.name] = null;
- }
- var charset = param.charset || 'gb2312';
- /*创建一个DocumentFragment充当script元素的父容器,这样的好处是不需要将节点真正的加入到DOM树中*/
- var frag = document.createDocumentFragment(), script = document.createElement('script');
- script.charset = charset;
- /*将callback函数定义在DocumentFragment上,script返回后可以直接调用到该函数*/
- frag[param.name] = function () {
- /*调用用户传入的callback*/
- param.success && param.success.apply(null, arguments);
- /*使用完成后清除垃圾信息*/
- clear();
- };
- /*注册script的onreadystatechange事件
- *一般情况,IE6下script的readyState会经历loading、interactive和loaded,
- *IE7下没有interactive(表示加载的数据虽然未完成但已经可以使用)状态,
- *而在interactive(IE7下则是loading之后和loaded之前)状态后请求的callback数据其实已经到达并可用
- *也就是说如果正常请求到数据,则在loaded状态前定义在DocumentFragment上的Callback就会被执行。
- *由于加载成功后onreadystatechange事件会被清空,因此一旦readyState到达了loaded状态则表示加载错误。
- */
- script.onreadystatechange = function () {
- if (script.readyState == 'loaded') {
- param.error && param.error();
- clear();
- }
- };
- script.src = param.url;
- frag.appendChild(script);
- }
function loadIECallback(param){ param = initParam(param); /*清除,防止内存泄露*/ function clear(){ frag = script = script.onreadystatechange = frag[param.name] = null; } var charset = param.charset || 'gb2312'; /*创建一个DocumentFragment充当script元素的父容器,这样的好处是不需要将节点真正的加入到DOM树中*/ var frag = document.createDocumentFragment(), script = document.createElement('script'); script.charset = charset; /*将callback函数定义在DocumentFragment上,script返回后可以直接调用到该函数*/ frag[param.name] = function () { /*调用用户传入的callback*/ param.success && param.success.apply(null, arguments); /*使用完成后清除垃圾信息*/ clear(); }; /*注册script的onreadystatechange事件 *一般情况,IE6下script的readyState会经历loading、interactive和loaded, *IE7下没有interactive(表示加载的数据虽然未完成但已经可以使用)状态, *而在interactive(IE7下则是loading之后和loaded之前)状态后请求的callback数据其实已经到达并可用 *也就是说如果正常请求到数据,则在loaded状态前定义在DocumentFragment上的Callback就会被执行。 *由于加载成功后onreadystatechange事件会被清空,因此一旦readyState到达了loaded状态则表示加载错误。 */ script.onreadystatechange = function () { if (script.readyState == 'loaded') { param.error && param.error(); clear(); } }; script.src = param.url; frag.appendChild(script); }
其他浏览器
- function loadOther(param){
- param = initParam(param);
- /*清除,防止内存泄露*/
- function clear(){
- iframe.callback = iframe.errorcallback = null;
- iframe.src = 'about:blank', iframe.parentNode.removeChild(iframe), iframe = null;
- }
- var charset = param.charset || 'gb2312';
- /*采用iframe可以对错误进行响应*/
- var iframe = document.createElement('iframe');
- iframe.style.display = 'none';
- /*在iframe的frameElement上定义callback*/
- iframe.callback = function () {
- param.success && param.success.apply(null, arguments);
- clear();
- };
- iframe.errorcallback = function () {
- param.error && param.error();
- clear();
- };
- try {
- document.body.appendChild(iframe);
- var doc = iframe.contentWindow.document;
- doc.open();
- doc.write(
- /*在iframe内容中定义真是的callback函数,以供正确请求到数据后进行响应,如果正确地请求到数据则会执行success回调并删除对错误的响应函数*/
- '<script type="text\/javascript">function ' + param.name + '() { window.frameElement.callback.apply(null, arguments); }</script>'
- /*写入script标签请求数据*/
- + '<script type="text\/javascript" src="' + param.url + '" charset="' + charset + '"></script>'
- /*如果没有请求道正确的数据,则会顺利执行完下面的脚步片段,对错误进行响应*/
- + '<script type="text\/javascript">window.setTimeout("try { window.frameElement.errorcallback(); } catch (exp) {}", 1)</script>'
- );
- doc.close();
- } catch (exp) {}
- }
function loadOther(param){ param = initParam(param); /*清除,防止内存泄露*/ function clear(){ iframe.callback = iframe.errorcallback = null; iframe.src = 'about:blank', iframe.parentNode.removeChild(iframe), iframe = null; } var charset = param.charset || 'gb2312'; /*采用iframe可以对错误进行响应*/ var iframe = document.createElement('iframe'); iframe.style.display = 'none'; /*在iframe的frameElement上定义callback*/ iframe.callback = function () { param.success && param.success.apply(null, arguments); clear(); }; iframe.errorcallback = function () { param.error && param.error(); clear(); }; try { document.body.appendChild(iframe); var doc = iframe.contentWindow.document; doc.open(); doc.write( /*在iframe内容中定义真是的callback函数,以供正确请求到数据后进行响应,如果正确地请求到数据则会执行success回调并删除对错误的响应函数*/ '<script type="text\/javascript">function ' + param.name + '() { window.frameElement.callback.apply(null, arguments); }</script>' /*写入script标签请求数据*/ + '<script type="text\/javascript" src="' + param.url + '" charset="' + charset + '"></script>' /*如果没有请求道正确的数据,则会顺利执行完下面的脚步片段,对错误进行响应*/ + '<script type="text\/javascript">window.setTimeout("try { window.frameElement.errorcallback(); } catch (exp) {}", 1)</script>' ); doc.close(); } catch (exp) {} }
使用实例
最简洁的方式如下,这里省略了name和key,那么实际上在实现时会自动生成一个带时间戳的callback name,并且默认key为callback,因此最后请求的URL应该为:
http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=xxx&callback=_callback_func_123123112。
- Connection.loadCallback({
- url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword,
- success: successHandle1,
- error: errorHandle
- });
Connection.loadCallback({ url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword, success: successHandle1, error: errorHandle });
此外,如果返回的callback函数名是写死的,则需要指定该callback的名字,即参数中的name,使用方式如下:
- Connection.loadCallback({
- name: 'JSCallback',
- url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword,
- success: successHandle1,
- error: errorHandle
- });
Connection.loadCallback({ name: 'JSCallback', url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword, success: successHandle1, error: errorHandle });
此外,如果返回的callback函数名是通过传参来指定的,则可以通过name和key来配置,其中name是callback函数名,key则是传参过程中的参数名,使用方式如下:
- Connection.loadCallback({
- name: 'JSCallback',
- key: 'cb',
- url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword,
- success: successHandle1,
- error: errorHandle
- });
Connection.loadCallback({ name: 'JSCallback', key: 'cb', url: 'http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=' + keyword, success: successHandle1, error: errorHandle });
上例中,发出的请求URL应该类似:http://youa.baidu.com/suggest/se/s?cmd=suggest&type=kwd&max_count=10&keyword=&cb=JSCallback
总结一下
- 在IE的实现方案中,将DocumentFragment充当script元素的父容器,并且将用户定义的callback函数定义在DocumentFragment上,这样的好处是不需要将节点真正的加入到DOM树中即可完成callback功能。
- 在IE的实现方案中,利用script在readyState为loaded之前就已经可以做交互的原理实现了出错处理,如果请求正确则在readyState转变为loaded之前就应经完成响应,并删除script,所以如果readyState转变到loaded则视为error。
- 在IE之外的实现方案中,利用iframe实现了出错处理,脚本是顺序执行的,正确的响应执行后便销毁iframe,这样便没有机会执行后面的出错响应,只有当请求出错时方会执行。
相关推荐
封装了两种callback,一种是返回string类型,在子类进行json解析;一种是传入泛型的javabean,解析完了传回子类
用ASP.NET Callback 和JavaScript 高速访问数据库用ASP.NET Callback 和JavaScript 高速访问数据库用ASP.NET Callback 和JavaScript 高速访问数据库
主要介绍了JavaScript中使用Callback控制流程介绍,本文讲解了callback的一些问题和优化后的写法并给出代码实例,需要的朋友可以参考下
主要介绍了JavaScript callback回调函数用法,结合实例形式分析了callback回调函数的概念、功能、应用场景及相关使用技巧,需要的朋友可以参考下
以上实现了在vs编译器中用c++开始编写回调函数,新建dll文件主要为回调函数,同时通过新建vs空项目实现对dll的调用
json+callback实现无刷新demo,短小精悍
此文适合JavaScript入门级选手阅读,在JavaScript里什么叫Callback“回调函数”,把方法b当做一个参数传递个方法a,当方法a执行完后执行另外一个指定函数(这里是b函数),感兴趣的朋友可以了解下哈
ASP.NET2.0实现无刷新客户端回调的Callback机制
一个基于ajax+ASP.NET实现的客户端Callback 控件源码例子。
主要介绍了Javascript中的Callback方法浅析,本文讲解了什么是callback、Javscript Callback、Callback是什么、Callback实例等内容,需要的朋友可以参考下
简单易懂,快速了解WCF如何CallBack
promise.js 是 Promises 的轻量级 JavaScript 实现。 Promises 提供了 callback-passing 的替代方案,异步函数返回一个 Promise 对象可附加到 callbacks 中。 示例代码: function asyncfoo() { var p = new ...
这是一个及其简单的但是又实用的callBack
callback
本文实例分析了C++中回调函数(CallBack)的用法。分享给大家供大家参考。具体分析如下: 如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。 其错误是普通的C++成员函数都隐含了一个传递...
利用路由器CallBack功能实现拨号网络的安全控制.pdf
C++中回调(CallBack)的使用思路C++中回调(CallBack)的使用思路C++中回调(CallBack)的使用思路
这篇文章主要介绍了JavaScript回调函数callback用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JavaScript回调函数的使用是很常见的,引用官方回调...
xe datasnap CallBack