Mouseevent

Элементы, связанные с событием

Чаще всего нужно узнать, на каком элементе сработало событие.

Например, мы поймали на внешнем ‘е и хотим знать, на каком из внутренних элементов оно на самом деле произошло.

В Internet Explorer у объекта для этого есть свойство , в остальных браузерах, работающих по рекомендациям W3C, для этого используется .

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

1

2
3
Ссылка

<div class="d1" 
  onclick="*!*t=event.target||event.srcElement; alert(t.className)*/!*"
>
<span class="number">1</span>
    <div class="d2">
        <span class="number">2</span>
        <div class="d3">
            <span class="number">3</span>
        </div>
        <a class="d2a" href="javascript:void(0)">Ссылка</a>
    </div>
</div>

Javascript-обработчик в примере висит только на внешнем диве и выглядит примерно так:

function(event) {
  // получить объект событие.
  // вместо event лучше писать window.event
  event = event || window.event

  // кросс-браузерно получить target
  var t = event.target || event.srcElement

  alert(t.className)
}

Для событий и предусмотрен способ получить как элемент на который курсор мыши перешел, так и элемент, с которого он перешел.

Эти свойства — в W3C, и в Internet Explorer.

// Обработчик для mouseover
function mouseoverHandler(event) {
	event = event || window.event
	var relatedTarget = event.relatedTarget || event.fromElement
	// для mouseover
	// relatedTarget - элемент, *!*с которого*/!* пришел курсор мыши
}

// Обработчик для mouseout
function mouseoutHandler(event) {
	event = event || window.event
	var relTarg = event.relatedTarget || event.toElement
	// для mouseout
	// relatedTarget - элемент, *!*на который*/!* перешел курсор мыши
}

Свойство дополняет . В нем всегда находится информация о втором элементе, участвовавшем в событии.

Поэтому его можно получить для IE, взяв то свойство из , которое не равно :

if (!e.relatedTarget && e.fromElement) {
  e.relatedTarget = (e.fromElement==e.target) ? e.toElement : e.fromElement
}

При всплытии — событие по очереди вызвает обработчики на элементе-триггере и дальше, вверх по документу.

По мере всплытия, текущим элементом каждый раз становится новый. Иначе говоря. текущий элемент — это тот, к которому в данный момент «доплыло» событие.

Стандартный способ получить текущий элемент — использовать переменную .

Например, при клике на внутренний , код в этом примере последовательно отмечает элементы, на которых регистрируется всплывающее событие:

1

2

3

<div class="d1" onclick="highlightMe(this)">1
    <div class="d2" onclick="highlightMe(this)">2
        <div class="d3" onclick="highlightMe(this)">3</div>
    </div>
</div>

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

Для удаления обработчиков событий из элементов предназначен метод unbind(). Вызов метода unbind() без указания аргументов приводит к удалению всех обработчиков, связанных со всеми событиями, для всех элементов, содержащихся в объекте jQuery.

Можно прибегнуть к более избирательному подходу и передать события, которые вы хотите открепить от элементов, методу unbind() в качестве аргумента, как показано в примере ниже:

В этом примере сначала со всеми элементами img связывается обработчик событий mouseenter и mouseout, а затем из элемента img с атрибутом src, содержащим rose, с помощью метода unbind() открепляется лишь событие mouseout, тогда как обработчик события mouseenter остается на месте.

Главный поток

В каждом окне выполняется только один главный поток, который занимается выполнением JavaScript, отрисовкой и работой с DOM.

Он выполняет команды последовательно, может делать только одно дело одновременно и блокируется при выводе модальных окон, таких как .

Дополнительные потоки тоже есть

Есть и другие, служебные потоки, например, для сетевых коммуникаций.

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

Web Workers

Существует спецификация Web Workers, которая позволяет запускать дополнительные JavaScript-процессы(workers).

Они могут обмениваться сообщениями с главным процессом, но у них свои переменные, и работают они также сами по себе.

Такие дополнительные процессы не имеют доступа к DOM, поэтому они полезны, преимущественно, при вычислениях, чтобы загрузить несколько ядер/процессоров одновременно.

Обработчик события как атрибут элемента

Это самый старый способ назначения обработчиков события и наименее используемый на данный момент. Для того чтобы его добавить, необходимо к имени события добавить приставку «on» и записать примерно такой код:

Обработчик события как атрибут

JavaScript

<button onclick=’alert(«Событие произошло!»)’>Нажми меня</button>

1 <button onclick=’alert(«Событие произошло!»)’>Нажмименя<button>

Нажми меня

Можно вызвать функцию, в которую можно передать один или несколько аргументов:

Обработчик события как атрибут элемента

JavaScript

<script>
function change(element, color){
element.style.backgroundColor = color;
}
</script>
<p onclick=»change(this, ‘red’)»>Кликни здесь, и этот абзац станет красным.
Но только один раз.</p>
<p onclick=»change(this, ‘lime’)»>Кликни здесь, и этот абзац станет зеленым.
Но только один раз.</p>

1
2
3
4
5
6
7
8
9

<script>

functionchange(element,color){

element.style.backgroundColor=color;

}
</script>

<ponclick=»change(this, ‘red’)»>Кликниздесь,иэтотабзацстанеткрасным.

Нотолькоодинраз.<p>

<ponclick=»change(this, ‘lime’)»>Кликниздесь,иэтотабзацстанетзеленым.

Нотолькоодинраз.<p>

Пример этого кода:

Кликни здесь, и этот абзац станет красным. Но только один раз.

Кликни здесь, и этот абзац станет зеленым. Но только один раз.

Недостатком этого способа является то, что, если добавлять обработчики событий нужно к большому количеству элементов, то, во-первых, легко допустить ошибку в каком-нибудь из них, а во-вторых, при изменении кода сделать это придется долго. И опять-таки можно допустить ошибку.

Использовать этот способ нужно в учебных целях поначалу, а также тогда, когда это самый простой способ или нужно очень быстро добавить обработчик события к 1 элементу.

Свойства событий указателя

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

  • – уникальный идентификатор указателя, вызвавшего событие.

    Идентификатор генерируется браузером. Это свойство позволяет обрабатывать несколько указателей, например сенсорный экран со стилусом и мульти-тач (увидим примеры ниже).

  • – тип указывающего устройства. Должен быть строкой с одним из значений: «mouse», «pen» или «touch».

    Мы можем использовать это свойство, чтобы определять разное поведение для разных типов указателей.

  • – равно для основного указателя (первый палец в мульти-тач).

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

  • – ширина области соприкосновения указателя (например, пальца) с устройством. Если не поддерживается, например мышью, то всегда равно .
  • – высота области соприкосновения указателя с устройством. Если не поддерживается, например мышью, то всегда равно .
  • – степень давления указателя в диапазоне от 0 до 1. Для устройств, которые не поддерживают давление, принимает значение (нажато) либо .
  • – нормализованное тангенциальное давление.
  • , , – специфичные для пера свойства, описывающие положение пера относительно сенсорной поверхности.

Эти свойства большинством устройств не поддерживаются, поэтому редко используются. При необходимости, подробности о них можно найти в .

Пакеты событий

Некоторые события активируются группами: т.е. одно действие пользователя приводит к вызову нескольких событий.

Например, когда фокус переходит от одного поля к другому, событие возникает для одного поля, а — для другого. В принципе, это происходит одновременно (поскольку это является реакцией на одно действие пользователя), однако события всё равно возникают по очереди.

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

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

  1. Фаза перехвата для – выполняются все перехватывающие обработчики.
  2. Событие возникает для целевого элемента.
  3. Фаза всплывания для — событие возникает для всех родительских элементов
  4. (Для нет действия по умолчанию).
  1. Фаза перехвата – выполняются все перехватывающие обработчики.
  2. Событие возникает для целевого элемента.
  3. Фаза всплывания — событие возникает для всех родительских элементов
  4. Выполняется действие по умолчанию для .

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

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

Событие onclick javaScript и три способа обработки событий

Событие происходит во время одинарного щелчка кнопкой мыши. Обычно для события назначается обработчик, то есть функция, которая сработает, как только событие произошло. Обработать событие, т.е. отреагировать на него посредством скрипта, можно тремя способами. Рассмотрим их:

Пример: По щелчку на кнопке вывести диалоговое окно с сообщением «Ура!»

  1. Через свойство объекта с использованием пользовательской функции:

Скрипт:

function message() {
		alert("Ура!");
	}

html-код:

<body>
<form>
<input type="button" name= "myButton" onclick="message()" value="Щелкни!">
<form>

В данном примере в html-коде мы видим кнопку. У кнопки присутствует атрибут («по щелчку»), в значении которого стоит вызов функции с названием . Это пользовательская функция, описанная выше в скрипте. В самой функции выводится диалоговое окно, что и задано согласно заданию.
Скрипт при такой обработке события обычно находится в области документа

Через атрибут тега:

<body>
<form name="myForm">
<input type="button" name="myButton" 
    value="Щелкни!" onclick="javascript: alert('Ура!')">
<form>

Это упрощенный вариант обработки события, он подходит только для небольшого кода, когда необходимо выполнить один-два оператора. Иначе код будет плохочитаемым.
В качестве атрибута кнопки указывается («по щелчку»), а в качестве значения пишется скрипт из операторов с указанием на каком языке он написан (). В нашем случае оператор для вывода модального окна со словом «Ура!»

Через регистрацию функции-обработчика в качестве свойства элемента:

html-код:

<form name="myForm">
<input type="button" value="Щелкни!" id="myButton">
<form>

Скрипт:

document.myForm.myButton.onclick = message; 
function message() {
	alert('Ура!');
}

В html-коде здесь присутствует кнопка с атрибутом , который необходим для обращения к кнопке через скрипт.

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

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

Именно такой способ обработки событий максимально приближен к тому, который происходит, например, в ОС windows.

Как лучше выводить результаты примеров?

Важно: При вызове после окончания загрузки страницы (при обработке событий onclick, oninput, …), страница перезапишется, поэтому вызывать этот метод не рекомендуется. Для примеров лучше использовать метод .

добавляет html во время построения DOM

блокируют выполнение JS, пока пользователь не нажмёт OK

Рассмотрим все простые способы вывода отладочной информации:

  1. alert('str'); // показывает окошко
  2. document.write('htmlstr'); // пишет на страницу
  3. document.innerHTML += 'htmlstr'; // добавляет на страницу
  4. console.log('str'); // выводит в консоль браузерах

Задание Js8_5. Выполните задание по инструкции:

  1. Создайте веб-страницу и расположите в ней тег с изображением грустного смайлика.
  2. Щелчок на изображении () вызывает заданный метод (пользовательская функция):
<img id="smileImg" src="smile1.jpg" onclick="sayHello()" >

В скрипте опишите метод (функция ), который «спрашивает», как зовут пользователя, а затем приветствует его по имени, и меняет изображение на улыбающийся смайлик (свойство тега ):

function sayHello() { 
	var userName=prompt("Как вас зовут?");
	if(userName){
		alert(...);
		document.getElementById("smileImg"). ...=...;
	}
}

 =>>

Языки «над» JavaScript

Синтаксис JavaScript подходит не под все нужды. Разные люди хотят иметь разные возможности.

Это естественно, потому что проекты разные и требования к ним тоже разные.

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

Современные инструменты делают транспиляцию очень быстрой и прозрачной, фактически позволяя разработчикам писать код на другом языке, автоматически преобразуя его в JavaScript «под капотом».

Примеры таких языков:

  • CoffeeScript добавляет «синтаксический сахар» для JavaScript. Он вводит более короткий синтаксис, который позволяет писать чистый и лаконичный код. Обычно такое нравится Ruby-программистам.
  • TypeScript концентрируется на добавлении «строгой типизации» для упрощения разработки и поддержки больших и сложных систем. Разработан Microsoft.
  • Flow тоже добавляет типизацию, но иначе. Разработан Facebook.
  • Dart стоит особняком, потому что имеет собственный движок, работающий вне браузера (например, в мобильных приложениях). Первоначально был предложен Google, как замена JavaScript, но на данный момент необходима его транспиляция для запуска так же, как для вышеперечисленных языков.
  • Brython транспилирует Python в JavaScript, что позволяет писать приложения на чистом Python без JavaScript.

Есть и другие. Но даже если мы используем один из этих языков, мы должны знать JavaScript, чтобы действительно понимать, что мы делаем.

Отличия IE8-

Чтобы было проще ориентироваться, я собрал отличия IE8-, которые имеют отношение ко всплытию, в одну секцию.

Их знание понадобится, если вы решите писать на чистом JS, без фреймворков и вам понадобится поддержка IE8-.

Нет свойства

Обратим внимание, что при назначении обработчика через у нас есть , поэтому , как правило, не нужно, а вот при назначении через обработчик не получает , так что текущий элемент, если нужен, можно будет взять лишь из замыкания.

Вместо в IE8- используется

Если мы пишем обработчик, который будет поддерживать и IE8- и современные браузеры, то можно начать его так:

Для остановки всплытия используется код .

Кросс-браузерно остановить всплытие можно так:

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

Ещё раз хотелось бы заметить – эти отличия нужно знать при написании JS-кода с поддержкой IE8- без фреймворков. Почти все JS-фреймворки обеспечивают кросс-браузерную поддержку , и .

События мыши

Название Описание
.click() Устанавливает обработчик «клика» мышью по элементу, либо, запускает это событие
.dblclick() Устанавливает обработчик двойного «клика» мышью по элементу, либо, запускает это событие
.hover() Устанавливает обработчик двух событий: появления/исчезновения курсора над элементом
.mousedown() Устанавливает обработчик нажатия кнопки мыши, либо, запускает это событие
.mouseup() Устанавливает обработчик поднятия кнопки мыши, либо, запускает это событие
.mouseenter() Устанавливает обработчик появления курсора в области элемента, либо, запускает это событие
.mouseleave() Устанавливает обработчик выхода курсора из области элемента, либо, запускает это событие
.mousemove() Устанавливает обработчик движения курсора в области элемента, либо, запускает это событие
.mouseout() Устанавливает обработчик выхода курсора из области элемента, либо, запускает это событие
.mouseover() Устанавливает обработчик появления курсора в области элемента, либо, запускает это событие
.toggle() Поочередно выполняет одну из двух или более заданных функций, в ответ на «клик» по элементу

Отмена поведения браузера по умолчанию

Для некоторых событий предусмотрены действия по умолчанию, которые выполняются браузером, если источниками событий являются определенные элементы. Хорошим примером этого может служить щелчок на кнопке с атрибутом type, имеющим значение submit. Если элемент button находится внутри элемента form, то действием по умолчанию для браузера является отправка формы. Чтобы предотвратить выполнение этого действия, следует вызвать метод preventDefault() для объекта Event, как показано в примере ниже:

Пойдем дальше. Обычно вы отменяете действие по умолчанию для того, чтобы вместо него выполнить некоторые другие действия. Например, вы приостанавливаете отправку браузером формы, поскольку хотите сделать это с помощью Ajax. В приведенном примере можно обойтись без привлечения функции и использовать возможности метода bind(), как показано в примере ниже:

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

События объектов:

Событие Описание
bubbles показывает является ли событие — bubbles событием;
cancelable показывает является ли событие — cancelable событием;
currentTarget возвращает элемент, событие которого было вызвано;
defaultPrevented показывает был вызван метод preventDefault() для события;
eventPhase возвращает текущую фазу потока события;
isTrusted показывает является ли событие — trusted событием;
target возвращает элемент, который вызвал событие;
timeStamp возвращает время с момента срабатывания события;
type возвращает имя события элемента;
view возвращает ссылку объекту Window, где произошло событие;
preventDefault() предотвращает реагирование объекта на событие;
stopImmediatePropagation() предотвращает реагирование на прослушивание объекта 
stopPropagation() предотвращает реагирование объекта на дальнейшие события.

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

Событие клавиатуры запускается, когда пользователь нажимает или отпускает клавишу на клавиатуре. Вот некоторые часто используемые методы jQuery для обработки событий клавиатуры.

Метод нажатия клавиши keypress()

Метод jQuery keypress() задает функцию-обработчик событий к выбранным элементам (обычно элементам управления формы), которая выполняется, когда браузер получает ввод с клавиатуры от пользователя. В следующем примере отобразится сообщение, когда событие kypress запускается и сколько раз оно запускается при нажатии клавиши на клавиатуре.

<script type="text/javascript">
  $(document).ready(function(){
    var i = 0;
    $('input').keypress(function(){
      $("span").text(i += 1);
      $("p").show().fadeOut();
    });
  });
</script>

Метод нажатия клавиши keydown()

Метод jQuery keydown() задает функцию-обработчик событий к выбранным элементам (обычно элементам управления формы), которая выполняется, когда пользователь впервые нажимает клавишу на клавиатуре. В следующем примере будет отображаться сообщение о срабатывании события нажатия клавиш и о том, сколько раз оно срабатывает при нажатии клавиши на клавиатуре.

<script type="text/javascript">
  $(document).ready(function(){
    var i = 0;
    $('input').keydown(function(){
      $("span").text(i += 1);
      $("p").show().fadeOut();
    });
  });
</script>

Метод keyup()

Метод jQuery keyup() задает функцию-обработчик событий к выбранным элементам (обычно элементам управления формы), которая выполняется, когда пользователь отпускает клавишу на клавиатуре. В следующем примере будет отображаться сообщение, когда событие keyup вызывается и сколько раз оно запускается при нажатии и отпускании клавиши на клавиатуре.

<script type="text/javascript">
  $(document).ready(function(){
    var i = 0;
    $('input').keyup(function(){
      $("span").text(i += 1);
      $("p").show().fadeOut();
    });
  });
</script>

Отключаем выделение

Двойной клик мыши имеют побочный эффект, который может быть неудобен в некоторых интерфейсах: он выделяет текст.

Например, двойной клик на текст ниже выделяет его в дополнение к нашему обработчику:

Если зажать левую кнопку мыши и, не отпуская кнопку, провести мышью, то также будет выделение, которое в интерфейсах может быть «не кстати».

Есть несколько способов запретить выделение, о которых вы можете прочитать в главе Selection и Range.

В данном случае самым разумным будет отменить действие браузера по умолчанию при событии , это отменит оба этих выделения:

Теперь выделенный жирным элемент не выделяется при двойном клике, а также на нём нельзя начать выделение, зажав кнопку мыши.

Заметим, что текст внутри него по-прежнему можно выделить, если начать выделение не на самом тексте, а до него или после. Обычно это нормально воспринимается пользователями.

Предотвращение копирования

Если мы хотим отключить выделение для защиты содержимого страницы от копирования, то мы можем использовать другое событие: .

Если вы попытаетесь скопировать текст в , у вас это не получится, потому что срабатывание события по умолчанию запрещено.

Конечно, пользователь имеет доступ к HTML-коду страницы и может взять текст оттуда, но не все знают, как это сделать.

setInterval()

Эта функция, как и предполагается из названия, в основном используется для задержки функций, которые будут выполняться снова и снова, например анимации. Функция очень близка к , у них даже такой же синтаксис:

setInterval ( expression, interval );

Но разница тут вот в чём. запускает только единожды, в то время, как продолжает запускать на регулярной основе после заданного временного интервала, пока вы не скажете стоп.

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

// Hello показывается каждые 3 секундыlet timerId= setInterval(() => alert('Hello'), 3000);// Повторения прекращаются после 6 секунд с id таймера.setTimeout(() => { clearInterval(timerId); alert('Bye'); }, 6000);

Когда вам нужно использовать ? Когда вам не нужно вызывать в конце спланированной функции. Также, во время использования , фактически не существует задержки между одним срабатыванием настоящего выражения и последующим. А в существует относительно долгая задержка, во время выполнения выражения, вызова функции и выставления нового . Так что если вам нужен обычный точный таймер и надо, чтобы что-то делалось повторно после определенного временного интервала, тогда это ваш выбор.Итак, сейчас мы подобрались к самому интересному. А именно к . А про него нужно рассказать максимально подробно.

requestAnimationFrame()

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

Использование этого метода позволяет браузеру справиться с некоторыми затруднительными задачами связанными с анимацией, например такими как управление частотой кадров.

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

Что такое JavaScript?

Изначально JavaScript был создан, чтобы «сделать веб-страницы живыми».

Программы на этом языке называются скриптами. Они могут встраиваться в HTML и выполняться автоматически при загрузке веб-страницы.

Скрипты распространяются и выполняются, как простой текст. Им не нужна специальная подготовка или компиляция для запуска.

Это отличает JavaScript от другого языка – Java.

Почему JavaScript?

Когда JavaScript создавался, у него было другое имя – «LiveScript». Однако, язык Java был очень популярен в то время, и было решено, что позиционирование JavaScript как «младшего брата» Java будет полезно.

Со временем JavaScript стал полностью независимым языком со своей собственной спецификацией, называющейся ECMAScript, и сейчас не имеет никакого отношения к Java.

Сегодня JavaScript может выполняться не только в браузере, но и на сервере или на любом другом устройстве, которое имеет специальную программу, называющуюся «движком» JavaScript.

У браузера есть собственный движок, который иногда называют «виртуальная машина JavaScript».

Разные движки имеют разные «кодовые имена». Например:

  • V8 – в Chrome и Opera.
  • SpiderMonkey – в Firefox.
  • …Ещё есть «Trident» и «Chakra» для разных версий IE, «ChakraCore» для Microsoft Edge, «Nitro» и «SquirrelFish» для Safari и т.д.

Эти названия полезно знать, так как они часто используются в статьях для разработчиков. Мы тоже будем их использовать. Например, если «функциональность X поддерживается V8», тогда «Х», скорее всего, работает в Chrome и Opera.

Как работают движки?

Движки сложны. Но основы понять легко.

  1. Движок (встроенный, если это браузер) читает («парсит») текст скрипта.
  2. Затем он преобразует («компилирует») скрипт в машинный язык.
  3. После этого машинный код запускается и работает достаточно быстро.

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

event.defaultPrevented

Свойство установлено в , если действие по умолчанию было предотвращено, и , если нет.

Рассмотрим практическое применение этого свойства для улучшения архитектуры.

Помните, в главе Всплытие и погружение мы говорили о и упоминали, что останавливать «всплытие» – плохо?

Иногда вместо этого мы можем использовать , чтобы просигналить другим обработчикам, что событие обработано.

Давайте посмотрим практический пример.

По умолчанию браузер при событии (клик правой кнопкой мыши) показывает контекстное меню со стандартными опциями. Мы можем отменить событие по умолчанию и показать своё меню, как здесь:

Теперь в дополнение к этому контекстному меню реализуем контекстное меню для всего документа.

При правом клике должно показываться ближайшее контекстное меню.

Проблема заключается в том, что когда мы кликаем по элементу , то мы получаем два меню: контекстное меню для кнопки и (событие всплывает вверх) контекстное меню для документа.

Как это поправить? Одно из решений – это подумать: «Когда мы обрабатываем правый клик в обработчике на кнопке, остановим всплытие», и вызвать :

Теперь контекстное меню для кнопки работает как задумано. Но цена слишком высока. Мы навсегда запретили доступ к информации о правых кликах для любого внешнего кода, включая счётчики, которые могли бы собирать статистику, и т.п. Это слегка неразумно.

Альтернативным решением было бы проверить в обработчике , было ли отменено действие по умолчанию? Если да, тогда событие было обработано, и нам не нужно на него реагировать.

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

event.stopPropagation() и event.preventDefault()

Как мы можем видеть, и (также известный как ) – это две разные функции. Они никак не связаны друг с другом.

Архитектура вложенных контекстных меню

Есть также несколько альтернативных путей, чтобы реализовать вложенные контекстные меню. Одним из них является единый глобальный объект с обработчиком и методами, позволяющими хранить в нём другие обработчики.

Объект будет перехватывать любой клик правой кнопкой мыши, просматривать сохранённые обработчики и запускать соответствующий.

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

Понимание событий и обработчиков событий JavaScript

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

Когда происходит событие, вы можете использовать обработчик событий JavaScript (или Event Listener), чтобы обнаружить их и выполнить определенную задачу или набор задач. По соглашению имена для обработчиков событий всегда начинаются со слова «on», поэтому обработчик события для события click называется onclick, аналогично обработчик для события load называется onload, обработчик события blur называется onblur, и так далее.

Есть несколько способов назначить обработчик событий. Самый простой способ — добавить их непосредственно в начальный тег элементов HTML, используя специальные атрибуты обработчика событий. Например, чтобы назначить обработчик нажатия для элемента кнопки, мы можем использовать атрибут onclick, например:

<button type="button" onclick="alert('Clicked!')">Click Me</button>

Однако, чтобы отделить код JavaScript от кода HTML, вы можете настроить обработчик событий во внешнем файле JavaScript или в тегах <script></script>, например:

<button type="button" id="myButton">Click Me</button>
<script>
function showMessage() {
  alert('Clicked!');
}
document.getElementById("myButton").onclick = showMessage;
</script>

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector