Errors in some Apple's examples

26 views
Skip to first unread message

Matteo

unread,
Jan 8, 2009, 2:40:39 AM1/8/09
to iPhoneWebDev
I noticed that in some examples at developers.apple.com Apple is
adding event listeners on the fly and removing them as soon as they
are not required. In the drag-n-drop example they add the touchmove
and touchend events at the end of the touchstart:

this.element.addEventListener('touchmove', function(e) { return
self.onTouchMove(e) }, false);
this.element.addEventListener('touchend', function(e) { return
self.onTouchEnd(e) }, false);

and they try to remove them on touchend:

this.element.removeEventListener('touchmove',function(e){return
self.onTouchMove(e)},false);
this.element.removeEventListener('touchend',function(e){return
self.onTouchEnd(e)},false);

As far as I can tell there's no way to remove an anonymous function
with removeEventListener. Initially I thought it was a webkit feature
but it turned out that the events are indeed never removed, so at
every touchstart two new events are appended (a big memory problem).

a very quick and dummy solution could be to create the event with
something like:

this.element.addEventListener('touchmove', obj = function(e) { return
self.onTouchMove(e) }, false);

and remove it with:

this.element.removeEventListener('touchmove', obj, false);

I'm not trying to discredit the examples at developers.apple.com, they
are great source of inspiration. I know that the examples are just
there to show you the way... they are not meant to be cut-n-pasted on
real projects, but since I slipped on this issue, I thought it could
have been worth mentioning about it.

Antoine Quint

unread,
Jan 8, 2009, 11:23:07 AM1/8/09
to iphone...@googlegroups.com
Hi,

On Jan 8, 2009, at 08:40 , Matteo wrote:

> I noticed that in some examples at developers.apple.com Apple is
> adding event listeners on the fly and removing them as soon as they
> are not required. In the drag-n-drop example they add the touchmove
> and touchend events at the end of the touchstart:
>
> this.element.addEventListener('touchmove', function(e) { return
> self.onTouchMove(e) }, false);
> this.element.addEventListener('touchend', function(e) { return
> self.onTouchEnd(e) }, false);
>
> and they try to remove them on touchend:
>
> this.element.removeEventListener('touchmove',function(e){return
> self.onTouchMove(e)},false);
> this.element.removeEventListener('touchend',function(e){return
> self.onTouchEnd(e)},false);
>
> As far as I can tell there's no way to remove an anonymous function
> with removeEventListener. Initially I thought it was a webkit feature
> but it turned out that the events are indeed never removed, so at
> every touchstart two new events are appended (a big memory problem).

Indeed, this is a poor way (an no-op) way to deal with event handlers
scoped to a particular object. The most convenient way I know to do
this is to have your JS object implement the DOM EventListener
interface:

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener

For instance:

function MyClass () {
// say we have a this.element here
this.element.addEventListener('touchmove', this, false);
this.element.addEventListener('touchend', this, false);
// you can then remove event listeners with
// this.element.removeEventListener('touchmove', this, false);
}

// this is the sole method from EventListener to implement,
// and this is where events will be routed when "this" is used
// as the "listener" parameter of .addEventListener()
MyClass.prototype.handleEvent = function (event) {
switch (event.type) {
case 'touchmove' :
this.onTouchMove(event);
break;
case 'touchend' :
this.onTouchEnd(event);
break;
};

MyClass.prototype.onTouchMove = function (event) {
// do something here
};

MyClass.prototype.onTouchEnd = function (event) {
// do something here
};

This is a relatively lesser known way to deal with events within
scoped to a JS instance object, but it works great.

Antoine

Rick Schramm

unread,
Jan 8, 2009, 11:42:32 AM1/8/09
to iPhoneWebDev


On Jan 8, 2:40 am, Matteo <mat...@gmail.com> wrote:
> I noticed that in some examples at developers.apple.com Apple is
> adding event listeners on the fly and removing them as soon as they
> are not required. In the drag-n-drop example they add the touchmove
> and touchend events at the end of the touchstart:
>
> this.element.addEventListener('touchmove', function(e) { return
> self.onTouchMove(e) }, false);
> this.element.addEventListener('touchend', function(e) { return
> self.onTouchEnd(e) }, false);
>
> and they try to remove them on touchend:
>
> this.element.removeEventListener('touchmove',function(e){return
> self.onTouchMove(e)},false);
> this.element.removeEventListener('touchend',function(e){return
> self.onTouchEnd(e)},false);

LOL. That dog don't hunt.

>
> As far as I can tell there's no way to remove an anonymous function
> with removeEventListener. Initially I thought it was a webkit feature
> but it turned out that the events are indeed never removed, so at
> every touchstart two new events are appended (a big memory problem).

Yep. Beware of examples from strangers, regardless of the domain.

>
> a very quick and dummy solution could be to create the event with
> something like:
>
> this.element.addEventListener('touchmove', obj = function(e) { return
> self.onTouchMove(e) }, false);
>
> and remove it with:
>
> this.element.removeEventListener('touchmove', obj, false);

Something like that.

>
> I'm not trying to discredit the examples at developers.apple.com, they

You succeeded in discrediting a bad example. No need to apologize for
that.

Ishan Anand

unread,
Jan 8, 2009, 12:46:30 PM1/8/09
to iphone...@googlegroups.com
File a bug report with apple. http://bugreporter.apple.com/
Reply all
Reply to author
Forward
0 new messages