The event listener cannot be unbound

As a newcomer to javascript, I'm facing an issue that I couldn't find answers to despite searching extensively. Here is my problem: I have a module or class where I am attempting to create a draggable component on the screen. The objective is to listen for mousemove events when the user first clicks on it and then remove these event listeners once the user releases the mouse.

The code appears simple and straightforward, and it works fine when not inside an IIFE (Immediately-Invoked Function Expression). However, the removeEventListener doesn't seem to work as expected. I suspect it has something to do with closures, scope, or some other concept that I am missing. Your help will be greatly appreciated. Below is the code:

MyClass.js

 var myNamespace = myNamespace || {};
 (function(myNamespace){

     var onMouseDragDown = function(e){
          window.addEventListener("mousemove", onMouseDragMove,true);
          window.addEventListener("mouseup", onMouseDragUp,false);
       };

      var onMouseDragUp = function(e){
         // This code executes, but the events CONTINUE to be triggered after removing the event listener

        //The following lines do not seem to have any effect whatsoever even though they are executed when the user releases the mouse button
      window.removeEventListener("mousemove", onMouseDragMove, true);
      window.removeEventListener("mouseup", onMouseDragUp,false);
  };

  var onMouseDragMove = function(e){
      console.log('moving');
   };

   myNamespace.MyClass = function(param){
      this._param = param;
      this._div = document.createElement('div');  
      this._div = ....

      this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);
   }

   myNameSpace.MyClass.prototype.getDiv = function (){
      return this._div;
   }
)(myNameSpace);

Index.html

...

function onCreateNewDocumentClicked(event){
    var myObject = new myNamepace.MyClass(someParams);
    document.body.appendChild(mdi.getDiv());
}

Answer №1

If you want to remove an event listener, make sure to provide the exact function that was used when adding it originally.
The issue arises from the fact that bind() generates a new function each time it is called, resulting in :

someFunc.bind(someObj) !== someFunc.bind(someObj)

In order to effectively remove an event listener, it is necessary to retain the initial function provided during addition.

Therefore, store the listener upon addition for future removal purposes :

var someListener = someFunc.bind(someObj);
element.addEventListener("--", someListener ) ;

// later on :
element.removeEventListener('--', someListener);

I have created a brief demonstration here; clicking the first button will trigger an alert saying 'hello'.
By attempting to remove the listener with a fresh bind call, it remains unchanged.
However, removing the stored function accomplishes the task successfully.

http://jsbin.com/EjevIQA/2/edit

Edit : It is unnecessary to add or remove a listener on each draggable div individually. Instead, you can listen for click events within the window and utilize the 'target' property to determine which specific div was clicked.
You may need to halt propagation or prevent default actions if a handled div gets clicked, depending on your requirements.

The event handler would appear as follows:

 function handleMouseDown(e) {
     // Check which mouse button was clicked (0=left, 2=right)
     var button = e.button;
     // Get the target element
     var target = e.target ;
     // Verify if the target is a draggable object
     ...
     ... otherwise return.
     // Perform necessary actions to initiate dragging.
     ...
     // To prevent the click from triggering default behavior or bubbling:
     e.stopPropagation();
     e.preventDefault();
 } 

Add this event listener once on the window or document object:

document.addEventListener("mousedown", handleMouseDown)

Check out my simple demo where clicking on a div displays its identification:
http://jsbin.com/ilavikI/2/edit

Answer №2

Is it possible that when you use

 .bind(this) 

within

  this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);

it doesn't actually return the exact function you intend to remove?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a problem when trying to create a node in Neo4j using Node.js

Here is my code for a Node.js application using Neo4j: var neo4j = require('neo4j-driver').v1; var express = require('express'); var logger = require('morgan'); var path = require('path'); var bodyParser =require(&a ...

When performing the operation number.tofixed in Typescript, it will always return a string value instead of a double datatype as expected from parseFloat

let value = 100 value.toFixed(2) -> "100.00" parseFloat(value.toFixed(2)) -> 100 I am encountering an unexpected result with the double type when input is 100.36, but not with 100.00. Framework: loopback4 ...

Error encountered: The Bootstrap modal() function is showing as undefined when using npm modules

Every time I attempt to call $("#myDiv").modal(), an error occurs. The error message reads: Uncaught TypeError: undefined is not a function This error has popped up in different scenarios, with various parameters being passed to modal(). Many solutions o ...

Tips for showing error messages in response to exceptions

My function is supposed to display the response text that comes back from ex.responseText. However, every time I attempt it, it returns as "undefined" even though the text is there. onError: function (ex) { $('<div>' + ex._message + &a ...

"XMLHttpRequest 206 Partial Content: Understanding the Importance of Partial

I need help with making a partial content request using an XMLHttpRequest object in JavaScript. Currently, I am trying to load a large binary file from the server and want to stream it similar to how HTML5 video is handled. While setting the Range header ...

The Vue component appears to be missing from the HTML code

I recently began learning Vue.js in school, and for my first assignment I need to print a h2 from a Vue component. However, I am having trouble getting it to work. Below is the code for the Vue component that I have created. var app = new Vue({ ...

Utilizing React JS: Displaying or Concealing Specific Components Based on the URL Path

Is there a way to dynamically change the navbar items based on the URL without having separate navbar components for each side? My current navbar design features 3 links on the left side and 3 links on the right, but I want to display only one side at a ti ...

Using npm: Managing Redirects

Does anyone have suggestions on how to manage redirects using the Request npm from websites like bitly, tribal, or Twitter's t.co URLs? For instance, if I need to access a webpage for scraping purposes and the link provided is a shortened URL that wil ...

Offspring of div should have equal height without the top and bottom padding

Looking to ensure that the height of child divs matches the height of the parent divs. Currently, the divs expand as the page is resized. This is for search results, so there are multiple identical code blocks. function matchHeight() { $result = $(&a ...

Limit the Datepicker in MUI (v5) to only accept two-digit years

I am currently using the MUI (v5) Datepicker for capturing user birthday information. The Datepicker has been localized to German language, resulting in the input format DD.MM.YYYY. However, many German users prefer using a shorter year format like DD.MM. ...

Adjust the appearance of an element based on user selection from a dropdown menu under certain circumstances

I am working on creating a dropdown menu using a JavaScript array. My goal is to display a specific span element when certain options are selected. For instance, I want the span to be shown only when options "a" and "c" are selected, but not when option " ...

Binding textarea data in Angular is a powerful feature that allows

I am looking to display the content from a textarea on the page in real time, but I am struggling to get the line breaks to show up. Here is my current code snippet: app.component.html <div class="ui center aligned grid">{{Form.value.address}}< ...

Issue with Google Finance JSON response not functioning as expected in Chrome and Firefox browsers, yet appears to be working properly in

I am currently working on a JavaScript project that involves fetching STOCK data from the Google Finance API. When I manually paste the link into my browser, I can successfully retrieve the JSON response: // [ { "id": "22144" ,"t" : "AAPL" ,"e" : "NASDAQ ...

Utilizing React with a Bootstrap Select element populated by an API call. Following form submission, I aim to automatically deselect the previously selected

After submitting the form, I am trying to reset the state to an empty value for the dropdown menu, but the selected item still appears before submitting the form. Any assistance in identifying the issue would be greatly appreciated. Thank you. Please see ...

What are the techniques used to minimize JavaScript functions?

Is there a more efficient way to reduce the amount of JavaScript code needed for functions that share the same call procedure? I'm struggling to find a clear explanation but here's the code snippet below... JavaScript: $(function() { $( &a ...

Can passing parameters between nested map functions cause any issues?

While attempting to navigate to a page in reactjs and pass parameters using the useNavigate hook, I encounter an unexpected token error as soon as I include the navigation within the anchor tag. <a onClick={() ={ ...

React fails to recognize the key prop

When creating a list of TSX elements, I utilized the following code: this.productsModel = this.state.products.map(o => ( <Grid.Column key> However, I encountered a warning from React: Warning: Each child in a list should have ...

Compatibility of HTML5 websites with Internet Explorer

Following a tutorial on HTML5/CSS3, I meticulously followed each step to create a basic website. While the demo of the site worked perfectly in Internet Explorer 8 during the tutorial, my own version did not display correctly when viewed in IE8. I discove ...

Why does the return value of a function in Node.js and JavaScript sometimes appear as undefined?

I am completely stumped by this issue. I've been trying to figure it out, but so far, no luck.. this is the code snippet function part1(sql, controltime, headers_view, results_view, tmp){ var timerName = "QueryTime"; var request = ne ...

jQuery not refreshing properly

I'm currently in the process of creating a script to switch the language on a website using PHP and Ajax/jQuery. I would like the page content to refresh without having to reload the entire page. So far, this is what I have come up with: $( "a[data-r ...