Javascript jQuery将事件处理程序连接到对象';s方法被激发
我正在尝试执行上述操作,但它似乎只适用于用户事件,如单击、鼠标悬停等 我来自dojo背景,您可以在这里执行以下操作:Javascript jQuery将事件处理程序连接到对象';s方法被激发,javascript,jquery,Javascript,Jquery,我正在尝试执行上述操作,但它似乎只适用于用户事件,如单击、鼠标悬停等 我来自dojo背景,您可以在这里执行以下操作: var obj = { method: function(){alert("hello world"); } $(obj).on("method", function(){ alert("the method was invoked"); }); $(obj).bind("method", function(){ alert("the method was invoked");
var obj = { method: function(){alert("hello world"); }
$(obj).on("method", function(){ alert("the method was invoked"); });
$(obj).bind("method", function(){ alert("the method was invoked"); });
更具体地说,我试图将事件处理程序绑定到自定义jQuery小部件上调用的方法 您可以使用jQuery实现这一点:
dojo.connect(obj, "method", function(){ alert("the method was invoked"); });
如果您可以依赖ECMAScript 5功能(因为您的所有目标浏览器都有ES5,或者因为您已经加载了ES5 shim/shiv),那么您可以使用(因为它是一个shim/shiv功能):
当然,在任何一种情况下,方法调用中的这个
将不再是钩住事件的元素(它将是obj
)。您应该接受方法中的事件参数(例如,e
),然后使用e.target
(对于事件发生的元素)或e.delegateTarget
(对于挂接事件的元素,它可能是e.target
)。您可以使用jQuery来完成这项工作:
dojo.connect(obj, "method", function(){ alert("the method was invoked"); });
如果您可以依赖ECMAScript 5功能(因为您的所有目标浏览器都有ES5,或者因为您已经加载了ES5 shim/shiv),那么您可以使用(因为它是一个shim/shiv功能):
当然,在任何一种情况下,方法调用中的
这个
将不再是钩住事件的元素(它将是obj
)。您应该接受方法中的事件参数(例如,e
),然后使用e.target
(对于事件起源的元素)或e.delegateTarget
(对于挂接事件的元素,它可能是e.target
).这并没有完全回答我最初提出的关于绑定到普通javascript对象的方法调用的问题,但我最终选择了:
$(obj).on("eventName", obj.method.bind(obj));
而不是我最初尝试的:
_method: function(){
this.element.trigger("customEventName");
}
//...elsewhere
$("#WidgetNode").bind("customEventName", function(){ alert("invoked!"); });
对于那些好奇dojo是如何做到这一点的人…
此代码允许您使用dojo.connect将处理程序连接到任何javascript对象上的任何方法调用
//此文件由TurboAjax组提供,由Dojo CLA授权
//低级授权机制
dojo.\u侦听器={
//创建一个调度程序函数
getDispatcher:function(){
//以下注释不符合规定,以防止克隆它们
//在返回的函数中。
//-实际位于侦听器数组(ls)中的索引(i)将
//不在Array.prototype中。这是“稀疏数组”技巧
//这让我们免受那些随意使用内置函数的libs的攻击
//物体
//-使用当前作用域调用侦听器(此)
返回函数(){
var ap=Array.prototype,c=arguments.callee,ls=c.\u侦听器,t=c.target;
//返回值来自原始目标函数
var r=t&&t.apply(这是参数);
//制作侦听器数组的本地副本,使其在处理过程中不可变
var-lls;
//>>includeStart(“connectRhino”,kwArgs.profileProperties.hostenvType==“rhino”);
如果(!dojo.isRhino){
//>>包括(“连接犀牛”);
//>>includeStart(“connectBrowser”,kwArgs.profileProperties.hostenvType!=“rhino”);
lls=[]混凝土(ls);
//>>includeEnd(“连接浏览器”);
//>>includeStart(“connectRhino”,kwArgs.profileProperties.hostenvType==“rhino”);
}否则{
//FIXME:在Rhino中,在稀疏数组上使用concat会产生密集数组。
//注意,如果数组A有元素[0,2,4],那么在Rhino下,“concat[].A”
//结果为[0,1,2,3,4],其中元素1和3的值为“未定义”
//“A.slice(0)”具有相同的行为。
lls=[];
对于(ls中的var i){
lls[i]=ls[i];
}
}
//>>包括(“连接犀牛”);
//在目标函数之后调用侦听器
用于(lls中的var i){
如果(!(ap中的i)){
lls[i]。应用(此,参数);
}
}
//返回值来自原始目标函数
返回r;
}
},
//将侦听器添加到对象
添加:函数(/*Object*/source、/*String*/method、/*function*/listener){
//每当调用“方法”时,“侦听器”将具有相同的作用域。
//尝试为侦听器支持上下文对象导致
//复杂性。
//在这里提供“一次”功能非常重要
//因为侦听器可能是dojo.hitch调用的结果,
//在这种情况下,对同一挂接装置目标的两个引用将不起作用
//应该是同等的。
source=source | | dojo.global;
//源方法可以是null、dispatcher或其他函数
var f=来源[方法];
//确保调度员
如果(!f | |!f.|侦听器){
var d=dojo._listener.getDispatcher();
//原始目标函数是特殊的
d、 目标=f;
//dispatcher保存侦听器列表
d、 _侦听器=[];
//将源重定向到调度程序
f=来源[方法]=d;
}
//合同要求返回一个句柄,该句柄可以
//标识此侦听器以断开连接。
//
//句柄的类型是私有的。下面是作为整数实现的。
//DOM事件代码具有相同的约定,但句柄是函数
//在非IE浏览器中。
//
//我们可以有单独的前后侦听器列表。
返回f._侦听器。按(侦听器);/*句柄*/
},
//从对象中删除侦听器
删除:函数(/*Object*/source、/*String*/method、/*Handle*/hand)
_method: function(){
this.onMethodInvoked();
},
onMethodInvoked: function(){
//stub for listening
}
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
// low-level delegation machinery
dojo._listener = {
// create a dispatcher function
getDispatcher: function(){
// following comments pulled out-of-line to prevent cloning them
// in the returned function.
// - indices (i) that are really in the array of listeners (ls) will
// not be in Array.prototype. This is the 'sparse array' trick
// that keeps us safe from libs that take liberties with built-in
// objects
// - listener is invoked with current scope (this)
return function(){
var ap=Array.prototype, c=arguments.callee, ls=c._listeners, t=c.target;
// return value comes from original target function
var r = t && t.apply(this, arguments);
// make local copy of listener array so it is immutable during processing
var lls;
//>>includeStart("connectRhino", kwArgs.profileProperties.hostenvType == "rhino");
if(!dojo.isRhino){
//>>includeEnd("connectRhino");
//>>includeStart("connectBrowser", kwArgs.profileProperties.hostenvType != "rhino");
lls = [].concat(ls);
//>>includeEnd("connectBrowser");
//>>includeStart("connectRhino", kwArgs.profileProperties.hostenvType == "rhino");
}else{
// FIXME: in Rhino, using concat on a sparse Array results in a dense Array.
// IOW, if an array A has elements [0, 2, 4], then under Rhino, "concat [].A"
// results in [0, 1, 2, 3, 4], where element 1 and 3 have value 'undefined'
// "A.slice(0)" has the same behavior.
lls = [];
for(var i in ls){
lls[i] = ls[i];
}
}
//>>includeEnd("connectRhino");
// invoke listeners after target function
for(var i in lls){
if(!(i in ap)){
lls[i].apply(this, arguments);
}
}
// return value comes from original target function
return r;
}
},
// add a listener to an object
add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
// Whenever 'method' is invoked, 'listener' will have the same scope.
// Trying to supporting a context object for the listener led to
// complexity.
// Non trivial to provide 'once' functionality here
// because listener could be the result of a dojo.hitch call,
// in which case two references to the same hitch target would not
// be equivalent.
source = source || dojo.global;
// The source method is either null, a dispatcher, or some other function
var f = source[method];
// Ensure a dispatcher
if(!f||!f._listeners){
var d = dojo._listener.getDispatcher();
// original target function is special
d.target = f;
// dispatcher holds a list of listeners
d._listeners = [];
// redirect source to dispatcher
f = source[method] = d;
}
// The contract is that a handle is returned that can
// identify this listener for disconnect.
//
// The type of the handle is private. Here is it implemented as Integer.
// DOM event code has this same contract but handle is Function
// in non-IE browsers.
//
// We could have separate lists of before and after listeners.
return f._listeners.push(listener) ; /*Handle*/
},
// remove a listener from an object
remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
var f = (source||dojo.global)[method];
// remember that handle is the index+1 (0 is not a valid handle)
if(f && f._listeners && handle--){
delete f._listeners[handle];
}
}
};
// Multiple delegation for arbitrary methods.
// This unit knows nothing about DOM,
// but we include DOM aware
// documentation and dontFix
// argument here to help the autodocs.
// Actual DOM aware code is in event.js.
dojo.connect = function(/*Object|null*/ obj,
/*String*/ event,
/*Object|null*/ context,
/*String|Function*/ method,
/*Boolean*/ dontFix){
// summary:
// Create a link that calls one function when another executes.
//
// description:
// Connects method to event, so that after event fires, method
// does too. All connected functions are passed the same arguments as
// the event function was initially called with. You may connect as
// many methods to event as needed.
//
// event must be a string. If obj is null, dojo.global is used.
//
// null arguments may simply be omitted.
//
// obj[event] can resolve to a function or undefined (null).
// If obj[event] is null, it is assigned a function.
//
// The return value is a handle that is needed to
// remove this connection with dojo.disconnect.
//
// obj:
// The source object for the event function.
// Defaults to dojo.global if null.
// If obj is a DOM node, the connection is delegated
// to the DOM event manager (unless dontFix is true).
//
// event:
// String name of the event function in obj.
// I.e. identifies a property obj[event].
//
// context:
// The object that method will receive as "this".
//
// If context is null and method is a function, then method
// inherits the context of event.
//
// If method is a string then context must be the source
// object object for method (context[method]). If context is null,
// dojo.global is used.
//
// method:
// A function reference, or name of a function in context.
// The function identified by method fires after event does.
// method receives the same arguments as the event.
// See context argument comments for information on method's scope.
//
// dontFix:
// If obj is a DOM node, set dontFix to true to prevent delegation
// of this connection to the DOM event manager.
//
// example:
// When obj.onchange(), do ui.update():
// | dojo.connect(obj, "onchange", ui, "update");
// | dojo.connect(obj, "onchange", ui, ui.update); // same
//
// example:
// Using return value for disconnect:
// | var link = dojo.connect(obj, "onchange", ui, "update");
// | ...
// | dojo.disconnect(link);
//
// example:
// When onglobalevent executes, watcher.handler is invoked:
// | dojo.connect(null, "onglobalevent", watcher, "handler");
//
// example:
// When ob.onCustomEvent executes, customEventHandler is invoked:
// | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
// | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
//
// example:
// When ob.onCustomEvent executes, customEventHandler is invoked
// with the same scope (this):
// | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
// | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
//
// example:
// When globalEvent executes, globalHandler is invoked
// with the same scope (this):
// | dojo.connect(null, "globalEvent", null, globalHandler);
// | dojo.connect("globalEvent", globalHandler); // same
// normalize arguments
var a=arguments, args=[], i=0;
// if a[0] is a String, obj was ommited
args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
// if the arg-after-next is a String or Function, context was NOT omitted
var a1 = a[i+1];
args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
// absorb any additional arguments
for(var l=a.length; i<l; i++){ args.push(a[i]); }
// do the actual work
return dojo._connect.apply(this, args); /*Handle*/
}
// used by non-browser hostenvs. always overriden by event.js
dojo._connect = function(obj, event, context, method){
var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
return [obj, event, h, l]; // Handle
}
dojo.disconnect = function(/*Handle*/ handle){
// summary:
// Remove a link created by dojo.connect.
// description:
// Removes the connection between event and the method referenced by handle.
// handle:
// the return value of the dojo.connect call that created the connection.
if(handle && handle[0] !== undefined){
dojo._disconnect.apply(this, handle);
// let's not keep this reference
delete handle[0];
}
}
dojo._disconnect = function(obj, event, handle, listener){
listener.remove(obj, event, handle);
}