Включение и выключение addeventlistener

Я не очень хороший программист, мне удалось перенести программу DOS в Windows, а затем из Windows в Javascript работает браузер, начиная с 2014 года. У меня есть несколько прослушивателей событий нажатия клавиш, которые запускаются на основе файла настроек .js при запуске. Я хотел бы добавить кнопки отключения и включения для включения и выключения прослушивателя, если это возможно (я знаю, что перехват Ctrl и Shift может показаться некоторым сомнительным)

if (usectrlshiftdnup) {

 // Trying to get Shift key 16 to step up a graph data set which works

 document.addEventListener('keydown', function (event) {
   if (event.keyCode === 16) {

     document.activeElement.blur();
     document.getElementById("upbutton").click(); 
     document.activeElement.blur();

   }
 });

 // Trying to get Ctrl key 17  to step down a graph data set which works

 document.addEventListener('keydown', function (event) {
   if (event.keyCode === 17) {

     document.activeElement.blur();
     document.getElementById("dnbutton").click(); 
     document.activeElement.blur();

   }
 });

Обычно я программирую методом проб и ошибок, немного прочитал о RemoveEvenListener, но решил, что на этот раз просто спрошу.

Поведение ключевого слова "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) для оценки ваших знаний,...
1
0
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете ввести уровень абстракции для управления активными в данный момент обратными вызовами прослушивателя. Что-то вроде ListenerManager.

class ListenerManager {
    listeners = [];

    storeListener(typeString, callback) {
        this.listeners.push([typeString, callback]);
        // Note that this function also automatically "enables" the stored listener
        document.addEventListener(typeString, callback);
    }

    enableListeners() {
        this.listeners.forEach((listener) => document.addEventListener(listener[0], listener[1]));
    }

    disableListeners() {
        this.listeners.forEach((listener) => document.removeEventListener(listener[0], listener[1]));
    }
}

Вы бы использовали это так:

let manager = new ListenerManager();
manager.storeListener("keydown", myCallback1);
manager.storeListener("keydown", myCallback2);

// Let's say you want to disable them all
manager.disableListeners();

// Later you want to enable them all again
manager.enableListeners();

В качестве альтернативы вы можете сделать это на более высоком уровне, что может быть проще, хотя и менее эффективно. Просто используйте глобальную логическую переменную, которую все соответствующие обратные вызовы вручную проверяют, чтобы определить, следует ли им игнорировать ввод.

let isEventsDisabled = false;

// Your callbacks would look something like:
function myCallback1(event) {
    // Guard clauses
    if (isEventsDisabled) return; // Relevant callbacks have this added for "disabling"
    if (event.keyCode !== 16) return;

    document.activeElement.blur();
    document.getElementById("upbutton").click(); 
    document.activeElement.blur();
}

// And you would register listeners "directly" the same way you have been doing
document.addEventListener("keydown", myCallback1);

// Let's say you want to disable them all
isEventsDisabled = true;

// Later you want to enable them all again
isEventsDisabled = false;

Спасибо. Я попробую поработать с этими предложениями. Я пытался добавить третий параметр, правда); в addEventListener, а затем вызывая RemoveEventListener также с третьим параметром, true); но это не сработало и не выдало никаких ошибок консоли.

Park 29.09.2023 17:02

Я в значительной степени понимаю ваш первый пример и ваш второй. Я подумал, что мне следует дать функциям параметров событий дискретные имена, такие как myCallback1 и myCallback2. (событие1 и событие2)

Park 29.09.2023 17:13

Третий необязательный параметр, если он передан как логическое значение, просто меняет способ срабатывания события (перехват события; вы можете прочитать больше здесь, но он не имеет особого отношения к вашему варианту использования, и его можно безопасно не указывать).

Cloud 30.09.2023 00:18

Хорошо, что если вы добавили с помощью true, вы также удалили с помощью true, но проблема, возможно, заключалась в копировании вашего обратного вызова — в конечном итоге вы создаете две отдельные лямбды, которые делают одно и то же. Важно отметить, что это не один и тот же объект функции, поэтому попытка удаления не приводит к удалению первоначально добавленной функции. Да, вам следует дать каждому обратному вызову имя, чтобы позже его можно было правильно удалить.

Cloud 30.09.2023 00:21

Глобальная логическая переменная во втором примере — это просто то, что вы можете придумать как программист (она не является частью какого-либо API). Думайте об этом как об ответе на вопрос: «Должен ли я игнорировать входные данные прямо сейчас?». Поэтому по умолчанию мы устанавливаем ответ false. Всякий раз, когда мы хотим игнорировать входные данные, мы устанавливаем для него значение true. Но чтобы использовать этот ответ, нам нужно действительно задать вопрос. Где мы это спрашиваем? Во всех ваших обратных вызовах. Таким образом, каждый обратный вызов проверяет логическую переменную с помощью оператора if, чтобы «задать» вопрос. Если он должен игнорировать, не продолжайте; если его не следует игнорировать, действуйте как обычно.

Cloud 30.09.2023 00:35

Хорошо, спасибо, Облако!

Park 30.09.2023 02:55

Облако, работает как шарм! И Элегантный! Как программист-любитель, я очень завидую таким людям, как вы. Мне пришлось поставить var Listeners = []; над объявлением класса, поскольку консоль пинала Listeners.push как слушатели неопределенные. На самом деле, я был профессиональным пианистом в течение 50 лет и совершил ошибку, написав в 1990 году графическую программу анализа фортепианных струн (клипер с графической библиотекой), портированную на Windows в 1996 году и, наконец, портированную на javascript/браузер в 2014 году с использованием AMCharts. Поддерживаю программу для мастеров по ремонту фортепиано с самого первого дня. Огромное вам спасибо!!! На этот раз поленился.

Park 30.09.2023 07:01

Рад помочь. Интересная история. Я думаю, неопределённую ошибку можно исправить, используя this.listeners внутри методов класса — опечатка с моей стороны. Я отредактирую ответ соответственно. Тогда вам не придется ставить var listeners вне самого класса. Если у вас где-то хранится исходный код, мне было бы любопытно взглянуть.

Cloud 30.09.2023 07:15

Это устарело. Теперь есть AbortController, его намного проще использовать, см. stackoverflow.com/questions/68967007/…

NVRM 30.09.2023 08:56

Да, добавив это. to Listeners.push позволяет объявить массив внутри класса. Все работает так, как вы предложили и исправили. У меня нигде не опубликован исходный код (работает локально). Однако концепция переноса отдельного приложения Windows на JavaScript/браузер делает приложение кроссплатформенным, и я подозреваю, что может быть много ситуаций, когда это может быть применимо в положительном смысле. Я попробую запустить его с помощью onFocus() и onBlur() внутри текстового поля и текстовой области. Единственный другой вопрос может заключаться в отключении только одного из того, что есть в массиве, например, прослушивателя [0]. Я думаю, как-нибудь поп и толкнуть.

Park 30.09.2023 18:37

А, так вот почему вы отключите слушателей, я полагаю, за то, что они печатают. А необходимость индивидуального отключения объясняет добавление нескольких отдельных прослушивателей для одного и того же события. Если у вас не так много слушателей и вам необходимо индивидуальное отключение, то может быть проще просто отказаться от менеджера и написать несколько удобных функций, каждая из которых добавляет/удаляет один из именованных обратных вызовов. Например, enableShift(), disableShift(), enableControl(), disableControl() и т. д. Пока передаваемые вами обратные вызовы не дублируются, это будет работать.

Cloud 01.10.2023 03:47

Спасибо, Облако! У меня есть 8 прослушивателей клавиш Ctrl/Shift, F1/F2, [/], которые все повышают или поднимают ноту на графике, чтобы показать/редактировать данные струнного масштаба. Esc, чтобы очистить данные в сетке данных, и F9, чтобы заново построить график. Большинство из них включается или выключается в редактируемом установочном файле. Все данные представляют собой числа, за исключением файла заметок с информацией о фортепиано, поэтому отключите Shift/Ctrl для прописных букв и вставьте. Ваше решение позаботится о том, что мне нужно. Legacy использует пропущенный тип, и я еще не нашел решения для этого, поэтому Esc для пустых полей. Еще раз спасибо. Я новичок в Stack Overflow, но с момента перехода на JavaScript это много раз помогало.

Park 01.10.2023 19:30

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