Argo


  我的地盘Ajax做主
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Function.createCallback 如何传递多个参数到回调函数中

Posted on 2008-01-02 20:30  Argo  阅读(3057)  评论(4编辑  收藏

今天由于项目需要要编写一个功能如下的封装Textbox控件的ASP.NET AJAX Client Behavior组件

  • 能够限制输入的字符数
  • 可以设置是否工作在插入模式(达到最大限制字符数时,如果是插入模式,可以在文本框任意位置继续输入字符,而光标后的字符依次向后移动)
  • 兼容IE7 Firefox Safari主流浏览器

考虑到文本框可单行也可多行,将来能要响应一些事件(比如发生字符截断时,触发Truncate事件)。在IE下我订阅了keypress,keyup,paste三个事件,代码如下:

今天由于项目需要要编写一个功能如下的封装Textbox控件的ASP.NET AJAX Client Behavior组件

  • 能够限制输入的字符数
  • 可以设置是否工作在插入模式(达到最大限制字符数时,如果是插入模式,可以在文本框任意位置继续输入字符,而光标后的字符依次向后移动)
  • 兼容IE7 Firefox Safari主流浏览器

考虑到文本框可单行也可多行,将来能要响应一些事件(比如发生字符截断时,触发Truncate事件)。在IE下我订阅了keypress,keyup,paste三个事件,代码如下:

this._onPasteHandler = Function.createDelegate(thisthis._onPaste);
this._onKeypressHnadler = Function.createDelegate(thisthis._onKeypress); 
this._onTruncateHandler = Function.createDelegate(thisthis._onKeyup);
$addHandler(
this.get_element(), "paste"this._onPasteHandler); 
$addHandler(
this.get_element(), "keypress"this._onKeypressHnadler); 
$addHandler(
this.get_element(), "keyup"this._onTruncateHandler); 


这里值得注意的是_onPaste方法。 

_onPaste: function(eventObject) { 
    
/// … 
    var pos = this._get_selectionStart(element); 
    
var handler = Function.createDelegate(thisthis._onKeyup); 
    
var callback = Function.createCallback(handler, null); 
    window.setTimeout(
function() {callback(eventObject, pos);}, 0); 
}, 

_onKeyup: 
function(eventObject, start) { 
    
/// … 
},


由于为了保证文本框不能由于粘贴操作导致字符超出限制的字符数,所以在粘贴事件中要对文本框内的字符进行处理,但是在此时文本框的内容还是原来的内容,将要粘贴的内容还没有粘贴到文本框内,所以我需要等粘贴操作完成时再进行处理。

讲到这里才说到主题上,我们先看一下ASP.NET AJAX的两个方法是如何定义的

 1Function.createCallback = function Function$createCallback(method, context) {
 2    /// <param name="method" type="Function"></param>
 3    /// <param name="context" mayBeNull="true"></param>
 4    /// <returns type="Function"></returns>
 5    var e = Function._validateParams(arguments, [
 6        {name: "method", type: Function},
 7        {name: "context", mayBeNull: true}
 8    ]);
 9    if (e) throw e;
10
11
12        
13    return function() {
14        var l = arguments.length;
15        if (l > 0{
16                        var args = [];
17            for (var i = 0; i < l; i++{
18                args[i] = arguments[i];
19            }

20            args[l] = context;
21            return method.apply(this, args);
22        }

23        return method.call(this, context);
24    }

25}

26
27Function.createDelegate = function Function$createDelegate(instance, method) {
28    /// <param name="instance" mayBeNull="true"></param>
29    /// <param name="method" type="Function"></param>
30    /// <returns type="Function"></returns>
31    var e = Function._validateParams(arguments, [
32        {name: "instance", mayBeNull: true},
33        {name: "method", type: Function}
34    ]);
35    if (e) throw e;
36
37
38        
39    return function() {
40        return method.apply(instance, arguments);
41    }

42}

43


通过上面的代码我们可以清楚地看到createDelegate是给指定的函数传递this指针,createCallback是给指定的函数传递一个参数context。但是回头看看我们_onKeyup函数需要两个参数,如何才能将两个参数传递过来呢?

var pos = this._get_selectionStart(element); // 准备第二个参数
var handler = Function.createDelegate(thisthis._onKeyup); // 传递当前this指针给函数_onKeyup
var callback = Function.createCallback(handler, null); // 创建callback 
window.setTimeout(function() {callback(eventObject, pos);}, 0); // 调用callback(eventObject, pos) 传递两个参数到_onKeyup函数中


总结:

使用Function.createCallback如果想传递一个参数给回调函数,只需要Function.createCallback(instance, context)就行了。

如果想传递多个参数给回调函数,需要先创建一个callback,然后自己调用将参数传递过去。这里有一个小技巧,比如要传递三个参数(args1, args2, args3)过去可以如下写:

var callback = Function.createCallback(handler, args3); 
callback(args1, args2); 


但是个人不推荐使用上面的写法,毕竟可读性不是很好。

其实还是使用原生态的最简单

var foo = function (instance, method, args) {
    
return function() {method.apply(instance, args);}
}


上面就可以使用foo(this, this._onKeyup, [args1, args2, args3])来传递参数了。

window.setTimeout(foo(thisthis._onKeyup, [args1, args2, args3]), 0);