Opened 9 years ago
Closed 8 years ago
#15002 closed defect (invalid)
cant use custom addEventListener and connect
Reported by: | Marcel Lucas | Owned by: | Kris Zyp |
---|---|---|---|
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)
Change History (5)
Changed 9 years ago by
Attachment: | dojo-connect_1.patch added |
---|
comment:1 Changed 9 years ago by
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 9 years ago by
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 8 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
This appears to be a resolved issue based on the feedback in the ticket. Closing as invalid. Please re-open if resolved.
native eventlistener check