javascriptclassaddeventlistenerremoveeventlistener

Uncaught ReferenceError when adding an EventListener


I'm trying to independently implement the ability to drag a block through a class. However getting a problem when trying to overlay an eventListener...

class Form {
    constructor() {
        //pass
    }
    DOMGenerator(elemClass) {
        const element = document.createElement('div');
        element.classList.add(elemClass);
        return element;
    }
    Draw() {
        const form = this.DOMGenerator('window'),
            label = this.DOMGenerator('window_label'),
            controls = this.DOMGenerator('window_controls'),
            close = this.DOMGenerator('close'),
            minimize = this.DOMGenerator('minimize'),
            maximize = this.DOMGenerator('maximize')

            label.addEventListener('mousedown', event => {
                const offsetX = event.offsetX;
                const offsetY = event.offsetY;
        
                document.addEventListener('mousemove', listener = event => {
                    let pageX = event.pageX;
                    let pageY = event.pageY;
            
                    form.style.left = `${pageX - offsetX}px`;
                    form.style.top = `${pageY - offsetY}px`;
                })
        
                document.addEventListener('mouseup', () => {
                    document.removeEventListener('mousemove', listener, false);
                })
            })
        
            controls.append(close, minimize, maximize);
            label.append(controls);
            form.append(label);
            document.body.append(form);
    }
}

new Form().Draw();

When executing the code and click on label element I get

Uncaught ReferenceError: listener is not defined
    at HTMLDocument.<anonymous> (main.js:31:63)
(anonymous) @ main.js:31

However, if I execute code OUTSIDE the class on an existing DOM element, then everything works as it should... So then I tried to change function declaration like this

document.addEventListener('mousemove', function listener(event) {
                    let pageX = event.pageX;
                    let pageY = event.pageY;
                
                    form.style.left = `${pageX - offsetX}px`;
                    form.style.top = `${pageY - offsetY}px`;
                })

It grabs the window and sticks it to the cursor, but fails to execute removeEventListener with the same error

Uncaught ReferenceError: listener is not defined
    at HTMLDocument.<anonymous> (main.js:31:63)

Solution

  • You haven't defined a function named listener anywhere.

    You can define a listener function outside.

    const listener = (event) => {
       // some code
    }
    
    element.addEventListener('mousemove', listener);
    element.removeEventListener('mousemove', listener);
    

    Here you are just defining a named function expression. You cannot access from outside with the name of the listener.

    document.addEventListener('mousemove', function listener(event) {
     let pageX = event.pageX;
     let pageY = event.pageY;
                
     form.style.left = `${pageX - offsetX}px`;
     form.style.top = `${pageY - offsetY}px`;
    })
    

    Let's try to access it. The result we will see is undefined.

    document.addEventListener('mousemove', function listener(event) {
          ...
    })
        
    console.log(typeof listener); -> undefined
    

    You can do something like below for the solution.

    Draw() {
          const form = ...
    
              let pageX;
              let pageY;
              let offsetX;
              let offsetY;
    
              const listener = (event) => {
                      pageX = event.pageX;
                      pageY = event.pageY;
              
                      form.style.left = `${pageX - offsetX}px`;
                      form.style.top = `${pageY - offsetY}px`;
              }
    
              label.addEventListener('mousedown', event => {
                  offsetX = event.offsetX;
                  offsetY = event.offsetY;
          
                  document.addEventListener('mousemove', listener)
          
                  document.addEventListener('mouseup', () => {
                      document.removeEventListener('mousemove', listener, false);
                  })
              })
    
             ...
    }