Установка события mouseup внутри класса

У меня есть единственный элемент на моей странице, и мне нужно обнаруживать события mosuedown и mouseup. Он работает нормально, но я решил переместить весь свой javascript внутри класса. вот что я придумал до сих пор:

class MyRectangle {
  constructor(elementId) {
    this.frame = $("#" + elementId);
    this.setListener();
  }

  setListener() {
    this.frame.on("mousedown", function(evt) {
      evt.preventDefault();
      console.info("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
      $(document).bind("mouseup", this.docMouseUp);
    });
  }

  docMouseUp(evt) {
    console.info("MOUSE UP" + " " + evt.pageX + ", " + evt.pageY);
    $(document).unbind("mouseup", this.docMouseUp);
  }

}

var myRect = new MyRectangle("rectangle");
#rectangle {
  width: 100px;
  height: 100px;
  background-color: #dfca45;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id = "rectangle">
</div>

Таким образом, событие mouseup никогда не запускается.

JSFiddle: https://jsfiddle.net/5hd7672v/

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
108
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что внутри docMouseUp и обратного вызова для функций событий mousedownthis больше не ссылается на экземпляр MyRectangle. Это потому, что эти функции вызываются jQuery, а контекст (переменная this) устанавливается на элемент, который сгенерировал событие.

Чтобы исправить это, вы можете привязать экземпляр MyRectangle следующим образом:

let self = this;
this.frame.on("mousedown", function(evt) { 
        evt.preventDefault();
        console.info("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
        $(document).bind("mouseup", self.docMouseUp.bind(self));
});

РЕДАКТИРОВАТЬ

Я пропустил звонок $(document).bind("mouseup", self.docMouseUp);. Чтобы это работало, вам нужно изменить ссылку на docMouseUp, чтобы она указывала на ту же функцию, которая была установлена ​​как обратный вызов.

class MyRectangle {
    constructor(elementId) {
        this.frame = $("#" + elementId);
        this.setListener();
    }

    setListener() {
        let self = this;
        this.docMouseUp = this.docMouseUp.bind(this);
        
        this.frame.on("mousedown", function(evt) { 
            evt.preventDefault();
            console.info("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
            $(document).bind("mouseup", self.docMouseUp);
        });
    }

    docMouseUp(evt) {
        console.info("MOUSE UP" + " " + evt.pageX + ", " + evt.pageY);
        $(document).unbind("mouseup", this.docMouseUp);     
    }

}

var myRect = new MyRectangle("rectangle");
#rectangle {
  width: 100px;
  height: 100px;
  background-color: #dfca45;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "rectangle">
</div>

Лучше использовать стрелочные функции, чем сохранять текущую ссылку this в отдельной переменной - это антишаблон.

CertainPerformance 27.04.2018 09:14

@CertainPerformance Это зависит от того, в этом случае неиспользование стрелочной функции дает возможность jQuery устанавливать контекст внутри анонимной функции.

Titus 27.04.2018 09:17

@CertainPerformance не может использовать их в IE на один раз: caniuse.com/#feat=arrow-functions

Bellian 27.04.2018 09:18

@Titus отвязка не работает должным образом. Обратные вызовы складываются, если вы нажимаете чаще.

Bellian 27.04.2018 09:26

Другие вопросы по теме