cpp

Обработка событий

При взаимодействии пользователя с приложением, окном и Web-страницей происходят события. События — это своего рода извещения системы о том, что пользователь выполнил какое-либо действие или внутри самой системы возникло некоторое условие. События возникают при щелчке на элементе, перемещении мыши, нажатии клавиши на клавиатуре, изменении размеров окна, окончании загрузки Web-страницы и т. д.

В предыдущих главах мы уже рассмотрели события объекта приложения (см. разд. 1.9), а также события окна (см. разд. 2.11). В этой главе мы рассмотрим события, которые генерируется при работе с Web-страницей.

Назначение и удаление обработчиков событий

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

<input type="button" value="Кнопка 1" onclick="handler1()">

При нажатии кнопки будет вызвана функция handler1().

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

document.getElementById('btn2').onclick = function() {
   console.log('Нажата кнопка 2');
};
document.getElementById('btn3').onclick = handler2;

Чтобы получить доступ к свойствам элемента нужно вначале получить ссылку на сам элемент с помощью метода getElementById() объекта document. В качестве значения метод принимает строку с идентификатором элемента. Далее указывается название события, которое совпадает и названием параметра тега. После оператора = задается анонимная функция или ссылка на функцию. Обратите внимание, при указании ссылки название функции указывается без круглых скобок. Если круглые скобки указать, то функция будет вызвана и результат ее работы станет значением свойства.

Первые два способа позволяют назначить только один обработчик. Попытка присвоить другое значение свойству приведет к удалению имеющегося обработчика. Третий способ лишен этого недостатка. Назначить обработчик события позволяет метод addEventListener(). Формат метода:

addEventListener(<Событие>, <Ссылка на функцию>[, <Фаза>]);

В параметре <Событие> указывается название события в виде строки без префикса on, например, click вместо onclick. Ссылка на функцию-обработчик указывается во втором параметре. В эту функцию в качестве параметра передается ссылка на объект event, а внутри функции через ключевое слово this доступна ссылка на текущий элемент. В параметре <Фаза> значение false используется в большинстве случаев. Учитывая, что это значение по умолчанию в Electron, следовательно параметр можно не указывать.

Пример назначения обработчиков различными способами приведен в листинге 7.1.

Листинг 7.1. Назначение обработчиков событий

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy" 
         content="default-src 'self' 'unsafe-inline'">
   <title>Назначение обработчиков событий</title>
</head>
<body>
   <input type="button" value="Кнопка 1" onclick="handler1()">
   <input type="button" value="Кнопка 2" id="btn2">
   <input type="button" value="Кнопка 3" id="btn3">
   <input type="button" value="Кнопка 4" id="btn4">
   <script>
      function handler1() {
         console.log('Нажата кнопка 1');
      }
      function handler2() {
         console.log('Нажата кнопка 3');
      }
      function handler3(e) {
         console.log('Нажата кнопка 4. handler3()');
      }
      function handler4(e) {
         console.log('Нажата кнопка 4. handler4()');
      }
      document.getElementById('btn2').onclick = function() {
         console.log('Нажата кнопка 2');
      };
      // Название функции указывается без круглых скобок
      document.getElementById('btn3').onclick = handler2;
      // Можно назначить сразу несколько обработчиков
      let btn4 = document.getElementById('btn4');
      btn4.addEventListener('click', handler3);
      btn4.addEventListener('click', handler4);
   </script>
</body>
</html>

Если обработчик назначался через параметр тега или свойство, то для удаления обработчика нужно присвоить свойству значение null, пустую строку или пустую анонимную функцию:

document.getElementById('btn2').onclick = function() {};

Если обработчик назначался через метод addEventListener(), то удалить его можно с помощью метода removeEventListener(). Формат метода:

removeEventListener(<Событие>, <Ссылка на функцию>[, <Фаза>]);

Обратите внимание, нужно обязательно иметь ссылку на обработчик, назначенный с помощью метода addEventListener(). Если при назначении обработчика использовалась анонимная функция, то удалить обработчик будет нельзя. Пример:

document.getElementById('btn4').removeEventListener('click', handler3);

Указатель this

При назначении обработчика с помощью свойства или метода addEventListener() внутри обработчика будет доступна ссылка на текущий элемент через указатель this. С помощью этого указателя можно получить доступ к свойствам элемента. Если обработчик назначается через параметр тега, то указатель нужно передать в качестве параметра. Получим текст на кнопке при ее нажатии (листинг 7.2).

Листинг 7.2. Указатель this

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>Указатель this</title>
</head>
<body>
   <input type="button" value="Кнопка 1" onclick="handler1(this)">
   <input type="button" value="Кнопка 2" id="btn2">
   <input type="button" value="Кнопка 3" id="btn3">
   <script>
      function handler1(elem) {
         console.log('Нажата кнопка ' + elem.value);
      }
      function handler2(event) {
         console.log('Нажата кнопка ' + this.value);
      }
      document.getElementById('btn2').onclick = function(event) {
         console.log('Нажата кнопка ' + this.value);
      };
      let btn3 = document.getElementById('btn3');
      btn3.addEventListener('click', handler2);
   </script>
</body>
</html>

Объект event

Объект event позволяет получить детальную информацию о произошедшем событии и выполнить необходимые действия. Объект event доступен только в обработчиках событий. При наступлении следующего события все предыдущие значения свойств сбрасываются.

При назначении обработчика с помощью метода addEventListener() или свойства объект event будет доступен через первый параметр. Если обработчик назначается через параметр тега, то объект нужно передать в обработчик в качестве параметра.

Объект event имеет следующие основные свойства:

  • type — строка, содержащая тип события. Возвращается в нижнем регистре и без префикса on. Например, при событии onclick свойство type равно click;
  • target — ссылка на элемент, который является источником события;
  • currentTarget — возвращает ссылку на элемент, в котором обрабатывается событие. Ссылается на тот же элемент, что и ключевое слово this внутри обработчика события. Значение свойства currentTarget может не совпадать со значением свойства target;
  • timeStamp — время возникновения события в миллисекундах.

Благодаря объекту event мы можем назначить один обработчик сразу для нескольких элементов и даже для нескольких типов событий. В листинге 7.3 приведен пример обработки нажатия кнопок внутри одного обработчика.

Листинг 7.3. Объект event

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>Объект event</title>
</head>
<body>
   <input type="button" value="Кнопка 1" onclick="handler(event)">
   <input type="button" value="Кнопка 2" id="btn2">
   <input type="button" value="Кнопка 3" id="btn3">
   <script>
      function handler(event) {
         console.log(event.type);
         console.log(event.target.value);
         console.log(event.currentTarget.value);
         console.log(event.timeStamp);
      }
      document.getElementById('btn2').onclick = handler;
      let btn3 = document.getElementById('btn3');
      btn3.addEventListener('click', handler);
   </script>
</body>
</html>

Действия по умолчанию

Для многих событий назначены действия по умолчанию, т. е. действия, которые Web-браузер выполняет в ответ на возникшие в документе события. Например, при щелчке на гиперссылке действием по умолчанию будет переход по указанному URL-адресу, нажатие кнопки Отправить приводит к отправке данных формы и т. д.

Иногда действия по умолчанию необходимо прервать. Для этого используются следующие свойства и методы объекта event:

  • cancelable — содержит true, если действие по умолчанию может быть отменено, и false — в противном случае;
  • preventDefault() — отменяет действие по умолчанию, если его можно отменить;
  • defaultPrevented — содержит true, если действие по умолчанию для текущего события было отменено в этом или предыдущем обработчике, и false — в противном случае.

Для отмены действия по умолчанию можно также внутри обработчика вернуть значение false.

В листинге 7.4 приведен пример прерывания перехода по гиперссылке.

Листинг 7.4. Прерывание действий по умолчанию

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>Прерывание действий по умолчанию</title>
   <script>
      function handler(e) {
         e.preventDefault();
         alert('Перехода по ссылке не будет!');
      }
   </script>
</head>
<body>
   <p>
      <a href="file.html"
         onclick="alert('Перехода по ссылке не будет!'); return false;">
         Нажмите для перехода по ссылке</a><br><br>
      <a href="file.html" onclick="handler(event);">
         Нажмите для перехода по ссылке</a>
   </p>
</body>
</html>

В этом примере рассмотрены два способа прерывания действия по умолчанию. В первой ссылке прерывание действия по умолчанию осуществляется возвратом значения false. Во второй ссылке с помощью свойств и методов объекта объекта event.

Всплывание событий

Что же такое "всплывание" событий? Давайте рассмотрим следующий пример (листинг 7.5).

Листинг 7.5. Всплывание событий

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>Всплывание событий</title>
   <script>
      function showMsg(msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
      }
   </script>
</head>
<body onclick="showMsg('Событие onclick - Документ')">
   <p onclick="showMsg('Событие onclick - Абзац')">
      Щелкните мышью
      <span style="color: red"
            onclick="showMsg('Событие onclick - SPAN')">
         здесь</span>
   </p>
   <div id="div1"></div>
</body>
</html>

В этом примере мы написали обработчики события onclick для трех элементов страницы — тела документа, абзаца и тега <span>. Попробуем щелкнуть левой кнопкой мыши на слове "здесь". В итоге вместо одного события onclick мы получим целую последовательность событий:

Событие onclick - SPAN
Событие onclick - Абзац
Событие onclick - Документ

Иными словами, событие onclick последовательно передается элементу-родителю. Для тега <span> элементом-родителем является абзац. А для абзаца элементом-родителем является само тело документа. Такое прохождение событий называется всплыванием событий.

Управлять всплыванием события позволяют следующие свойства и методы объекта event:

  • bubbles — содержит true, если текущее событие может всплывать, и false — в противном случае;
  • stopPropagation() — прерывает всплывание события.

Продемонстрируем прерывание всплывания события на примере (листинг 7.6).

Листинг 7.6. Прерывание всплывания события

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>Прерывание всплывания события</title>
   <script>
      function showMsg(e, msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
         e.stopPropagation();
      }
   </script>
</head>
<body onclick="showMsg(event, 'Событие onclick - Документ')">
   <p onclick="showMsg(event, 'Событие onclick - Абзац')">
      Щелкните мышью
      <span style="color: red"
            onclick="showMsg(event, 'Событие onclick - SPAN')">
         здесь</span>
   </p>
   <div id="div1"></div>
</body>
</html>

Попробуем теперь щелкнуть левой кнопкой мыши на слове "здесь". В итоге вместо трех событий мы получим только одно:

Событие onclick - SPAN

События документа

Перечислим основные события документа:

  • DOMContentLoaded — структура документа сформирована. Внутри обработчика этого события можно обращаться к элементам из скрипта и назначать обработчики событий для элементов страницы:
window.addEventListener('DOMContentLoaded', () => {
   // Здесь назначаем обработчики событий для элементов
});
  • onload — после полной загрузки Web-страницы. Внутри обработчика этого события можно обращаться ко всем элементам из скрипта и назначать обработчики событий для элементов страницы:
window.onload = function() {
   // Здесь назначаем обработчики событий для элементов
};
  • onscroll — при прокручивании содержимого элемента страницы, документа, окна или фрейма;
  • onresize — при изменении размеров окна;
  • onbeforeunload — перед выгрузкой документа;
  • onunload — непосредственно перед выгрузкой документа. Генерируется после события onbeforeunload.

Пример обработки событий документа приведен в листинге 7.7.

Листинг 7.7. События документа

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>События документа</title>
   <script>
      function showMsg(event, msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
         console.log(event);
      }
      window.addEventListener('DOMContentLoaded', (e) => {
         showMsg(e, 'Событие DOMContentLoaded');
      });
   </script>
</head>
<body onload="showMsg(event, 'Событие onload')"
      onscroll="showMsg(event, 'Событие onscroll')"
      onresize="showMsg(event, 'Событие onresize')">
   <div id="div1"></div>
   <div style="height: 600px"></div>
</body>
</html>

События мыши

Перечислим основные события мыши:

  • onmousedown — при нажатии кнопки мыши на элементе Web-страницы или самой странице;
  • onmouseup — при отпускании ранее нажатой кнопки мыши;
  • onclick — при щелчке мыши на элементе или на Web-странице;
  • ondblclick — при двойном щелчке мыши;
  • onmousemove — при любом перемещении мыши;
  • onmouseover — при наведении курсора мыши на элемент;
  • onmouseout — при выведении курсора мыши с элемента;
  • onselect — при выделении элемента;
  • oncontextmenu — при нажатии правой кнопки мыши для вывода контекстного меню;
  • onwheel — при вращении колесика мыши.

События возникают последовательно, например, последовательность событий при нажатии кнопки мыши на элементе страницы будет такой:

onmousedown
onmouseup
onclick

При двойном нажатии последовательность будет такой:

onmousedown
onmouseup
onclick
ondblclick

Это значит, что событие ondblclick возникает после события onclick.

Продемонстрируем обработку событий мыши на примере (листинг 7.8).

Листинг 7.8. События мыши

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>События мыши</title>
   <script>
      function showMsg(event, msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
         console.log(event);
      }
   </script>
</head>
<body onmousedown="showMsg(event, 'Событие onmousedown')"
      onmouseup="showMsg(event, 'Событие onmouseup')"
      onclick="showMsg(event, 'Событие onclick')"
      ondblclick="showMsg(event, 'Событие ondblclick')"
      oncontextmenu="showMsg(event, 'Событие oncontextmenu')"
      onwheel="showMsg(event, 'Событие onwheel')">
   <p onmouseover="showMsg(event, 'Событие onmouseover')"
      onmouseout="showMsg(event, 'Событие onmouseout')">
      Щелкните мышью в любом месте страницы
   </p>
   <div id="div1"></div>
   <div style="height: 600px"></div>
</body>
</html>

Получить информацию о событии позволяют следующие свойства:

  • clientX и clientY — координаты события (по осям X и Y) в клиентских координатах;
  • pageX и pageY — координаты события (по осям X и Y) относительно левого верхнего угла страницы;
  • offsetX и offsetY — координаты события (по осям X и Y) относительно контейнера;
  • button — число, указывающее нажатую кнопку мыши. Может принимать следующие значения:
  • 0 — нажата левая кнопка мыши;
  • 1 — нажата средняя кнопка;
  • 2 — нажата правая кнопка мыши;
  • relatedTarget — для события onmouseover содержит ссылку на элемент, с которого переместился курсор мыши. Для события onmouseout содержит ссылку на элемент, на который пользователь перемещает курсор мыши;
  • detail — для событий onclick, onmousedown и onmouseup возвращает количество выполненных щелчков мышью.
  • deltaX, deltaY и deltaZ — позволяют определить направление вращения колесика мыши при событии onwheel.

События клавиатуры

Перечислим события клавиатуры:

  • onkeydown — при нажатии клавиши на клавиатуре;
  • onkeypress — аналогично событию onkeydown, но генерируется только для символьных клавиш;
  • onkeyup — при отпускании ранее нажатой клавиши клавиатуры.

При нажатии клавиши на клавиатуре последовательность будет такой:

onkeydown
onkeypress
onkeyup

Продемонстрируем обработку событий клавиатуры на примере (листинг 7.9).

Листинг 7.9. События клавиатуры

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>События клавиатуры</title>
   <script>
      function showMsg(event, msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
         console.log(event);
      }
   </script>
</head>
<body onkeydown="showMsg(event, 'Событие onkeydown')"
      onkeypress="showMsg(event, 'Событие onkeypress')"
      onkeyup="showMsg(event, 'Событие onkeyup')">
   <p>Нажмите клавишу на клавиатуре</p>
   <div id="div1"></div>
</body>
</html>

Получить информацию о событии позволяют следующие свойства:

  • key — строка с буквой или описанием клавиши (например, "ArrowDown");
  • keyCode и which — код нажатой клавиши;
  • location — позволяет определить на какой клавиатуре была нажата клавиша:
  • 0 — на обычной клавиатуре;
  • 1 — функциональная клавиша, например, <Ctrl>, нажата слева;
  • 2 — функциональная клавиша, например, <Ctrl>, нажата справа;
  • 3 — на цифровой клавиатуре;
  • repeattrue, если клавиша удерживается нажатой;
  • shiftKeytrue, если была нажата клавиша <Shift>;
  • ctrlKeytrue, если была нажата клавиша <Ctrl>;
  • altKeytrue, если была нажата клавиша <Alt>;
  • metaKeytrue, если была нажата клавиша <Meta>.

События формы

Перечислим основные события формы:

  • onsubmit — при отправке данных формы;
  • onreset — при очистке формы;
  • onfocus — при получении фокуса элементом формы;
  • onchange — при изменении данных в текстовом поле и перемещении фокуса на другой элемент формы либо при отправке данных формы (наступает перед событием onblur);
  • onblur — при потере фокуса элементом формы;
  • oninput — периодически возникает в процессе ввода данных в поле ввода или в область редактирования;
  • oninvalid — возникает, например, если не заполнено обязательное поле.

Продемонстрируем обработку событий формы на примере (листинг 7.10).

Листинг 7.10. События формы

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Security-Policy"
         content="default-src 'self' 'unsafe-inline'">
   <title>События формы</title>
   <script>
      function showMsg(event, msg) {
         let div1 = document.getElementById('div1');
         div1.innerHTML += msg + '<br>';
         console.log(event);
      }
   </script>
</head>
<body>
   <form action="#" method="GET"
      onsubmit="showMsg(event, 'Событие onsubmit'); return false"
      onreset="showMsg(event, 'Событие onreset')">
      <div>
         Логин:<br>
         <input type="text" name="login"
                onfocus="showMsg(event, 'Событие onfocus')"
                onblur="showMsg(event, 'Событие onblur')"
                onchange="showMsg(event, 'Событие onchange')"
                oninput="showMsg(event, 'Событие oninput')"><br>
         E-mail:<br>
         <input type="text" name="email" required
                oninvalid="showMsg(event, 'Событие oninvalid')"><br>
         Описание:<br>
         <textarea name="descr" rows="10" cols="15"></textarea><br>
         <input type="reset" value="Очистить">
         <input type="submit" value="Отправить">
      </div>
   </form>
   <div id="div1"></div>
</body>
</html>

Учебник по Electron js
Учебник по Electron js в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp