Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #34112 > unrolled thread

removeeventlistener

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2017-10-16 14:29 +1100
Last post2017-10-28 20:00 +0200
Articles 6 — 4 participants

Back to article view | Back to comp.lang.javascript


Contents

  removeeventlistener Andrew Poulos <ap_prog@hotmail.com> - 2017-10-16 14:29 +1100
    Re: removeeventlistener Julio Di Egidio <julio@diegidio.name> - 2017-10-15 21:08 -0700
    Re: removeeventlistener Richard Maher <maher_rjSPAMLESS@hotmail.com> - 2017-10-16 13:06 +0800
    Re: removeeventlistener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-10-16 22:18 +0200
      Re: removeeventlistener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-10-28 19:48 +0200
        Re: removeeventlistener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-10-28 20:00 +0200

#34112 — removeeventlistener

FromAndrew Poulos <ap_prog@hotmail.com>
Date2017-10-16 14:29 +1100
Subjectremoveeventlistener
Message-ID<e4ednXbpPvgtunnEnZ2dnUU7-bXNnZ2d@westnet.com.au>
I have code that looks like this

function elementOver() {
   return function() {
     this.style...
   };
}

function setOver(elem) {
   for (var i = 0; elem.length; i++) {
     elem[i].addEventListener("mouseover", elementOver() );
   }
}

function disableOver(elem) {
   for (var i = 0; i < elem.length; i++) {
     elem[i].removeEventListener("mouseover", elementOver() );
   }
}

Adding the listener works but removing it doesn't. I don't understand 
why not nor how to remove the listeners?

Andrew Poulos

[toc] | [next] | [standalone]


#34113

FromJulio Di Egidio <julio@diegidio.name>
Date2017-10-15 21:08 -0700
Message-ID<6c946949-a87d-41be-9fb9-76c246b56760@googlegroups.com>
In reply to#34112
On Monday, October 16, 2017 at 5:30:06 AM UTC+2, Andrew Poulos wrote:
> I have code that looks like this
> 
> function elementOver() {
>    return function() {
>      this.style...
>    };
> }
> 
> function setOver(elem) {
>    for (var i = 0; elem.length; i++) {
>      elem[i].addEventListener("mouseover", elementOver() );
>    }
> }
> 
> function disableOver(elem) {
>    for (var i = 0; i < elem.length; i++) {
>      elem[i].removeEventListener("mouseover", elementOver() );
>    }
> }
> 
> Adding the listener works but removing it doesn't. I don't understand 
> why not nor how to remove the listeners?

Because you need to pass references to the same handler, but your two
separate invocations of the constructor create distinct instances.

To fix it, initialise a variable that is in the closure of both your
functions and pass that as a reference to add/removeEventListener.

(The extra-complexity of using a constructor function instead of
directly a function for the handler is pointless in your example,
but I'm assuming you know that.)

Julio

[toc] | [prev] | [next] | [standalone]


#34114

FromRichard Maher <maher_rjSPAMLESS@hotmail.com>
Date2017-10-16 13:06 +0800
Message-ID<os1eo9$1tb0$1@gioia.aioe.org>
In reply to#34112
On 16-Oct-17 11:29 AM, Andrew Poulos wrote:
> I have code that looks like this
> 
> function elementOver() {
>    return function() {
>      this.style...
>    };
> }
> 
> function setOver(elem) {
>    for (var i = 0; elem.length; i++) {
>      elem[i].addEventListener("mouseover", elementOver() );
>    }
> }
> 
> function disableOver(elem) {
>    for (var i = 0; i < elem.length; i++) {
>      elem[i].removeEventListener("mouseover", elementOver() );
>    }
> }
> 
> Adding the listener works but removing it doesn't. I don't understand 
> why not nor how to remove the listeners?
> 
> Andrew Poulos
My Guess is you're not passing the same "elem" to both functions.

BTW you should use delegation and let the event bubble up to a parent 
and then decide which child  target the mouse was on from that.

[toc] | [prev] | [next] | [standalone]


#34116

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-10-16 22:18 +0200
Message-ID<2412105.mvXUDI8C0e@PointedEars.de>
In reply to#34112
Andrew Poulos wrote:

> I have code that looks like this
> 
> function elementOver() {
>    return function() {
>      this.style...
>    };
> }
> 
> function setOver(elem) {
>    for (var i = 0; elem.length; i++) {
>      elem[i].addEventListener("mouseover", elementOver() );
>    }
> }
> 
> function disableOver(elem) {
>    for (var i = 0; i < elem.length; i++) {
>      elem[i].removeEventListener("mouseover", elementOver() );
>    }
> }
> 
> Adding the listener works but removing it doesn't. I don't understand
> why not nor how to remove the listeners?

Every time you call elementOver(), you create a *new* Function instance and 
return a reference to *that*.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#34222

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-10-28 19:48 +0200
Message-ID<1746259.PYKUYFuaPT@PointedEars.de>
In reply to#34116
Thomas 'PointedEars' Lahn wrote:

> Andrew Poulos wrote:
>> I have code that looks like this
>> 
>> function elementOver() {
>>    return function() {
>>      this.style...
>>    };
>> }
>> 
>> function setOver(elem) {
>>    for (var i = 0; elem.length; i++) {
>>      elem[i].addEventListener("mouseover", elementOver() );
>>    }
>> }
>> 
>> function disableOver(elem) {
>>    for (var i = 0; i < elem.length; i++) {
>>      elem[i].removeEventListener("mouseover", elementOver() );
>>    }
>> }
>> 
>> Adding the listener works but removing it doesn't. I don't understand
>> why not nor how to remove the listeners?
> 
> Every time you call elementOver(), you create a *new* Function instance
> and return a reference to *that*.

This answers the “why not” part of your question.

The answer to the “how” part (which I noticed only now) may not be obvious
if you could not find the answer to the “why not” part by yourself:

You need to store references to the listeners so that you can reuse them.

  /*
   * NOTE:
   * Easily maintainable code uses _plurals_ in the names of iterables
   */
  var elementOvers = [];

  function setOver (elements)
  {
    /*
     * NOTE:
     * You may want to use ES 5 [].forEach.apply(elements, …) or
     * ES 6 “for … of” on [].slice.call(elements) instead.
     *
     * In loops, cache the value of the “length” property unless you
     * expect its value to change and want to handle that.
     */
    for (var i = 0, len = elements.length; i < len; ++i)
    {
      /* NOTE:
       * You can still return the function reference instead.
       * Just keep in mind that in the way it is used here,
       * there is a closure over “i”.
       * 
       * Consider using CSS “:hover” selectors based on class selectors
       * instead of setting style properties here.
       */
      var elementOver = elementOvers[i] = function () {
        this.style...
      };

      /* NOTE: The third argument may not be “false” by default. */
      elements[i].addEventListener("mouseover", elementOver, false);
    }
  }

  function disableOver (elements)
  {
    for (var i = 0, len = elements.length; i < len; ++i)
    {
      elements[i].removeEventListener("mouseover", elementOvers[i]);
    }
  }

Usually one implements an event registry object for this purpose (which,
if the built-in Map object is supported, can register event listeners per 
element object even without using additional identifying properties now,
and certainly without host object augmentation), and one does not use many
user-defined *global* variables and functions.

HTH.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#34223

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-10-28 20:00 +0200
Message-ID<19619642.EfDdHjke4D@PointedEars.de>
In reply to#34222
Thomas 'PointedEars' Lahn wrote:

>   var elementOvers = [];
> 
>   function setOver (elements)
>   {
>     /*
>      * NOTE:
>      * You may want to use ES 5 [].forEach.apply(elements, …) or
>      * ES 6 “for … of” on [].slice.call(elements) instead.
>      *
>      * In loops, cache the value of the “length” property unless you
>      * expect its value to change and want to handle that.
>      */
>     for (var i = 0, len = elements.length; i < len; ++i)
>     {
>       /* NOTE:
>        * You can still return the function reference instead.
>        * Just keep in mind that in the way it is used here,
>        * there is a closure over “i”.
>        *
>        * Consider using CSS “:hover” selectors based on class selectors
>        * instead of setting style properties here.
>        */
>       var elementOver = elementOvers[i] = function () {
>         this.style...
>       };

Supplemental:

If all listeners for the same event implement the same algorithm, you only 
need to define *one* such function such that it can be shared across 
function execution contexts –

  var elementOver = function () {
    // …
  };

–, and re-use the reference to it:

  function (…)
  {
    for (…)
    {
      elements[i].addEventListener("mouseover", elementOver, false);
    }
  }

  …

  function (…)
  {
    for (…)
    {
      elements[i].removeEventListener("mouseover", elementOver);
    }
  }

That would be much more efficient then.
 
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web