Opened 2 years ago

Closed 13 months ago

#15002 closed defect (invalid)

cant use custom addEventListener and connect

Reported by: mlucas Owned by: kzyp
Priority: undecided Milestone: tbd
Component: Events Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:

Description

Hi,

I wrote a baseless EventDispatcher in JS for guys like me who were/are used to develop applications in ActionScript3 for Flash and have recently switched to JS development.

The Dispatcher covers the basic features described by W3C (especially currentTarget/target) plus
the niceties of Adobe (priorities) and dojo of course ('remove' Handler - so simple and great idea btw.!).

So after this introduction - the problem:

Descendants of EventDispatcher also provide callback methods for each EventType like:

	dispatchEvent(new Event("start"));
	onStart: function(e){...};
	
	dispatchEvent(new Event("progress"));
	onProgress: function(e){...}
	
	dispatchEvent(new Event("end"));
	onEnd: function(e){...}

When using one of those callbacks with dojo.connect the event will simply slip (the listener will not be called).

	dojo.connect(dispatcher,"onEnd",console.dir); //will never print out the event :(

Thats because dojo/_base/connect.js treats that EventDispatcher as a DOMNode for the fact it provides addEventDispatcher()

...
function connect_(obj, event, context, method, dontFix){
	method = lang.hitch(context, method);
	if(!obj || !(obj.addEventListener || obj.attachEvent)){
		// it is a not a DOM node and we are using the dojo.connect style of treating a
		...

Solution 1:
We could simply make that test a little more strict to only catch native code:

 function connect_(obj, event, context, method, dontFix){
 	method = lang.hitch(context, method);
-	if(!obj || !(obj.addEventListener || obj.attachEvent)){
+	var dispatcherFunc = obj.addEventListener || obj.attachEvent;
+		isNativeDispatcher = dispatcherFunc && Function.prototype.toString.call(dispatcherFunc).indexOf("[native code]")!=-1;
+	
+	if(!obj || !isNativeDispatcher){
 		// it is a not a DOM node and we are using the dojo.connect style of treating a
 		// method like an event, must go right to aspect
 		return aspect.after(obj || kernel.global, event, method, true);

Solution 2:
The condition that directly follows the above one converts the methodname to an event name;
intended for "onclick" to "click" and "onfocus" to "focus"
but in custom environment we more likely have this case:
"onEnd" to "End", or "onExecutionProgress" to "ExecutionProgress"

You may have guessed it - all associated event names to each "on"-callback start with lowercase letters.
In the end there will be a call to obj.addEventListener("ExecutionProgress") that will never get fired
because no such uppercase event type will get fired.

if(typeof event == "string" && event.substring(0, 2) == "on"){
-		event = event.substring(2);
+		event = event.charAt(2).toLowerCase()+event.substring(3);
 	}

Hope we can work something out.

Attachments (2)

dojo-connect_1.patch (754 bytes) - added by mlucas 2 years ago.
native eventlistener check
dojo-connect_2.patch (438 bytes) - added by mlucas 2 years ago.
event name to lowercase first letter

Download all attachments as: .zip

Change History (5)

Changed 2 years ago by mlucas

native eventlistener check

Changed 2 years ago by mlucas

event name to lowercase first letter

comment:1 Changed 22 months ago by kzyp

If you are EventDispatcher already has an addEventListener, why don't you provide the event name instead of the event handler?
dojo.connect(dispatcher,"end",console.dir);

It also may simplify things to use dojo/on.

comment:2 Changed 22 months ago by mlucas

OK that would work - as you said:

dojo.connect(dispatcher,"end",console.dir);
dojo.on(dispatcher,"end",console.dir);

so I can leave off these callbacks completely as their only purpose was to act as a connection point for simple dojo.connect calls.

Thanks for that

comment:3 Changed 13 months ago by kitsonk

  • Resolution set to invalid
  • Status changed from new to closed

This appears to be a resolved issue based on the feedback in the ticket. Closing as invalid. Please re-open if resolved.

Note: See TracTickets for help on using tickets.