Javacript — Запрос с событием click в virtualbox срабатывает редко


Содержание

Продвинутая работа с событиями в JavaScript

Учебник JavaScript

Практика

Работа с DOM

Практика

Некоторые продвинутые вещи

Рекомендованное ES6

Некоторые видео могут забегать вперед, тк к этому месту учебника мы прошли еще не весь ES6. Просто пропускайте такие видео, посмотрите потом.

Регулярки

Разное

Работа с канвасом

Практика

  • урок исключен (мало материала), по аяксу скоро будет отдельный учебник (много материала)
    Работа с
    AJAX в JavaScript
    Работа с
    AJAX + PHP

Контекст

Drag-and-Drop

  • Урок №
    Введение
    в ООП в стиле ES6
  • Урок №
    Основы
    работы с ООП
  • Урок №
    Наследование
    классов в JavaScript
    Продвинутая работа
    с классами на JavaScript
  • Урок №
    Применение
    ООП при работе с DOM
  • Урок №
    Практика
    по ООП в JavaScript
  • Тут скоро будут еще уроки
    по функциональному и прототипному
    стилю ООП.

Практика по ООП

Ваша задача: посмотрите, попробуйте повторить.

Практика

Promise ES6

Библиотека jQuery

Тк. jQuery устаревает, объявляю эти уроки не обязательными и выношу в конец учебника (так по уровню уроки середины учебника, если что). В перспективе переедет в отдельный учебник по jq.

В данном уроке мы с вами разберем все способы работы с событиями в JavaScript.

События через атрибуты

Вы уже хорошо знаете первый способ привязать событие к элементу — с помощью атрибута, например onclick (если вы не помните этого или пропустили — см. урок основы работы с событиями JavaScript).

Напомню еще раз этот способ на примере: сейчас по клику на кнопку сработает функция func, которая выводит на экран alert:

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

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

События через работу с атрибутами

По сути атрибут onclick является таким же атрибутом, как, к примеру, value. И, если мы могли менять атрибут value таким образом — elem.value, то точно также мы можем менять атрибут onclick.

Если мы сделаем так: elem.onclick = func, то привяжем к элементу elem функцию func. Посмотрите пример и под ним мы обсудим все нюансы этого способа:

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

Я уверен, что прочитав это, вы не до конца поймете то, что я хотел вам донести, поэтому запустите пример и еще раз перечитайте предыдущий абзац. Вот пример:

Теперь, зная эту страшную тайну, вернемся к строке elem.onclick = func — в данном случае я в атрибут onclick записываю исходный код функции, а не ее результат — и все работает. Если вы сделаете так — elem.onclick = func() — то запишите результат функции и ничего не будет работать.

Кстати, результатом функции func() будет undefined, так как у нее нет команды return. Напомню код функции, о которой идет речь:

Давайте вспомним метод setInterval (см. урок работа с таймерами в JavaScript), когда мы использовали его таким образом window.setInterval(timer, 1000) — в этом случае мы также писали функцию timer без круглых скобок, потому что нас интересовал не результат работы функции, а ее код.

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

Достоинства и недостатки такого способа

Давайте теперь обсудим достоинства и недостатки этого способа.

Достоинства

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

Давайте сделаем это. Получим все инпуты с помощью getElementsByTagName и в цикле привяжем каждому такое событие: пусть по клику каждый инпут выдает алертом текст ‘!’:

Теперь нажатие на любой инпут будет приводить к тому, что будет срабатывать функция func, которая алертом выводит ‘!’.


Использование this

Давайте усложним задачу и сделаем так, чтобы alert выводил содержимое атрибута value того инпута, на который кликнули мышкой.

Для этого нужно воспользоваться this, только не так, как мы это делали раньше. Раньше, когда мы писали событие прямо в атрибут, мы делали так: onclick=»func(this)», однако сейчас вот так — elems[i].onclick = func(this) — мы сделать не можем.

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

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

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

Так как правильно использовать this в нашей конструкции elems[i].onclick = func? На самом деле тут this доступен внутри функции func и он ссылается на тот элемент, в котором возникло событие, вызвавшее эту функцию. То есть, если я делаю клик по первому инпуту — в this будет лежать ссылка на него, а если по второму — то на него.

В данном случае считайте, что this — это будто переменная elem, полученная через getElementById. К примеру, elem.value позволяет обратиться к атрибуту value, значит this.value будет делать то же самое.

Итак, давайте все-таки решим нашу задачу — сделаем так, чтобы alert выводил содержимое атрибута value того инпута, на который кликнули мышкой:

Учтите, что если вы попытаетесь воспользоваться this внутри функции, которая была прописана прямо в атрибуте (то есть первым способом задать событие) — у вас ничего не выйдет. Смотрите пример неправильного кода:

В данном случае контекст выполнения таков, что this ссылается на window, а не на текущий элемент. Почему так — поговорим, когда вы разберете анонимные функции.

Напоминаю правильный вариант:

Недостатки

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

В следующем примере мы пытаемся привязать к событию onclick сразу две функции func1 и func2. Однако по клику на элемент сработает только вторая функция, так как она затрет первую:

В принципе, эту проблему легко обойти, если ввести еще и третью функцию func3. Привяжем к атрибуту onclick только func3, а она пусть вызывает func1 и func2 у себя внутри:

Как вы видите, этот недостаток не слишком существенный и его легко обойти. Только что вводится лишняя функция, что немного неудобно.

Однако, есть еще один недостаток — мы не можем легко отвязать от onclick, к примеру, только функцию func1, оставив func2 привязанным. Можно, конечно же, накрутить большие конструкции кода, однако это не нужно, если пользоваться еще более продвинутым способом привязать событие — через addEventListener. Давайте посмотрим, как с работать с этой функцией:

Работа с addEventListener

Метод addEventListener первым параметром принимает название события, а вторым — функцию, которую нужно привязать к этому событию. При этом имя события пишется без ‘on’: ‘click’ вместо ‘onclick’, ‘mouseover’ вместо ‘onmouseover’ и так далее. Имя функции (второй параметр) пишется без кавычек и без круглых скобок (зачем это нужно, мы с вами уже разобрали выше).

Давайте сделаем так, чтобы по клику на кнопку вызывалась функция func:

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

Если вы скопируете этот код и запустите его у себя — сработает и функция func1, и функция func2.

Работа с this для addEventListener

Мы с вами уже разбирали работу с this в случае, если привязывать события вторым способом (через свойство элемента). В случае с addEventListener this работает аналогичным образом — он будет ссылаться на тот элемент, в котором случилось событие.

Давайте посмотрим на примере: привяжем к кнопке событие onclick, которое будет запускать функцию func. Эта функция будет выводить на экран value нашей кнопки:

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

Здесь удобство работы с this в том, что не нужно создавать разные функции для разных элементов. Есть одна функция func, которая делает одно и то же, но для разных элементов и различаем мы их через this — на какой элемент кликнули — тот элемент и будет в this.

Ну, а сейчас получим массив кнопок с помощью getElementsByTagName и каждой из них привяжем функцию func.

В this будет лежать ссылка на ту кнопку, на которую вы нажали, и функция func выведет на экран именно ее value:

Удаление привязки через removeEventListener

Сейчас мы с вами займемся тем, что будем удалять привязанные к событию функции. Что у нас будет получаться: если, к примеру, к событию onclick привязаны функции func1 и func2, то мы сможем отвязать функцию func1, не затрагивая func2 и наоборот.

Давайте привяжем к элементу 3 функции: func1, func2 и func3, которые будут выводить на экран числа 1, 2 и 3:

А теперь сразу же после привязки отвяжем функции func1 и func2. Это делается с помощью метода removeEventListener, которая принимает те же параметры, что и addEventListener:

Если вы запустите этот пример, то увидите, что сработает функция func3, а первые две — нет.

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

Пусть при первом клике на кнопку сработают все 3 функции и при этом func1 и func2 отвяжутся от элемента. И при следующих кликах будет срабатывать только функция func3, которую мы не отвязываем.

Обратите внимание на this внутри функции — он указывает на наш элемент.

А в следующем примере мы ко всем кнопкам привяжем функцию func, которая будет выводить содержимое атрибута value той кнопки, на которую вы нажмете. А после этого функция func будет отвязываться от этой кнопки с помощью removeEventListener. И получится что каждая кнопка будет реагировать только на первое нажатие по ней (запустите код и проверьте это):

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку.

Когда все решите — переходите к изучению новой темы.

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

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

События в JS разделяются на системные: загрузка (load) и выгрузка (unload) страницы, события мыши (click, mouseover, mousemove и т.д.) и события клавиатуры (keypress, keydown, keyup).

Сегодня сосредоточимся на событиях мыши.

События мыши

К событиям мыши относятся:

  • click — клик;
  • dblclick — двойной клик;
  • mouseover — наведение курсора мыши на элемент;
  • mousemove — перемещение курсора мыши над элементом;
  • mouseout — уведение курсора мыши с элемента;
  • mousedown — нажатие левой кнопки мыши;
  • mouseup — отпускание левой кнопки мыши;
  • contextmenu — нажатие правой кнопки мыши и вывод контекстного меню.

Для того чтобы написать ответную реакцию на событие, создают обработчик события (event handler), который, как правило, представляет собой функцию.

Назначить обработчик события можно несколькими способами:


Рассмотрим все способы.

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

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

JavaScript: в callback функции теряется контекст. Как это обойти?

Разбираюсь значит с загрузкой данных с сервера и событийной моделью в JavaScript.

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

Код примерно такой:

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

Uncaught exception: TypeError: ‘this.calculate’ is not a function

Ошибка в FireFox:

TypeError: this.calculate is not a function initNext

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

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

Watchify событие обновления никогда не срабатывает в Virtualbox

Я пытаюсь получить watchify работать с Глотком но мне кажется, что «обновление» событие никогда не увольняет.

Вот мой gulpfile.js:

Однако, когда я явно смотреть файлы без watchify это работает:

Я пробовал много примеров, но с watchify расслоение никогда не обновляется.

Я бегу Gulp внутри Бродячей VM, хост OSX Yosemite, гость Ubuntu 14,04.

Любая помощь очень ценится!

Цукерберг рекомендует:  Java - Смысл интерфейсов.

Вы можете активировать его с помощью poll опции.

Из документации: opts.poll позволяет опрашивать отслеживать изменения. Если установлено значение истинно, то используется интервал опроса 100 мс. Если задано число, то , что количество миллисекунд будет интервал опроса. Для получения дополнительной информации см сторож в документации на «usePolling» и «интервал». Эта опция полезна , если вы смотрите тома NFS.

Это происходит потому , что watchify опирается на Inotify , чтобы обнаружить изменения файла , который прекрасно работает до тех пор , как они инициируются внутри виртуальной машины (например , с помощью touch этих файлов). Тем не менее, это не будет забрать изменения , выполненные снаружи из — за ограничений с VirtualBox , не вызвать соответствующие события в гостевой системе , когда файл был изменен в хост — системе. Видимо VMware страдает от той же проблемы .

Есть в настоящее время некоторые дискуссии , чтобы возвратиться к опросу для сетевых монтирует в watchify и chokidar (которые на watchify самом деле использует для просмотра файлов) , чтобы облегчить эту конкретную проблему:

У меня была такая же проблема, и я обнаружил, что это не так, что watchify событие обновления не срабатывает, то, что он не выдает каких-либо информацию журнала по умолчанию.

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

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

Обновление: Дэнни Moerkeke (ОП) писал: «Я уже пытался это проверить , обработчик срабатывает , и это не НО ваш ответ послал меня в правильном направлении причины , когда я редактировать файл с VI непосредственно в VM он работает рабочее пространство.! установлен в общей папку внутри бродяги и я бег глотки внутри этой виртуальной машины , а также. Когда я отредактировать файл в моем редакторе на хосте событие обновления не обожженные так , видимо , что — то здесь не очень хорошо работает с бродячими общими папками. Когда я запустить глоток на хосте все работает отлично. идея состояла в том , чтобы держать все внутри виртуальной машины , но на самом деле это хорошо (и быстрее!)»

Событие onclick в javascript и jquery на примерах

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

Все примеры будем рассматривать на теге «a» (ссылку). Пусть это не смущает, с другими тегами будет работать аналогичным образом.

Самый простой способ повесить событие onclick, это прописать его непосредственно в html теге:

В примере при нажатии на ссылку появляется всплывающее окно с сообщением. Дополнительно к действию мы прописали «return false;». Это требуется чтобы предотвратить переход по ссылке после срабатывания события «onclick». В других элементах (где нет аттрибута href) это можно опустить.

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

Выносим код события onclick в javascript-функцию

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

Но и здесь всё не идеально. Что делать, если событие требуется повесить на все ссылыки сайта, а их сотни? Кажется что это трудно, а на деле — меньше десяти строк кода. Задача решается с помощью селекторов. В примере опять будем производить действия с тегом «a», но ничего не мешает использовать вместо ссылки «img» или «div».

Вешаем onclick на элемент из javascript-кода

Рассмотим еще один способ, на мой взгляд, самый практичный и надежный. Хорош он тем, что событие можно повесить на множество элементов. Для этого требуется выбрать при помощи javascript-селекторов элементы, к которым требуется применить событие onclick.

Выбору элементов по селекторам можно посвятить отдельную тему, могу сказать только то, что согласно новой спецификации HTML5, их выбор стал прост и в javascript. Если Вы знакомы с jquery или CSS, то выбрать нужные элементы для Вас не составит труда. Например, так просто можно выбрать все элементы с классом «link» и повесить на них нужное действие:

Применяем jQuery

Если в проекте используется библиотека jQuery, то можно ещё упростить код. Рассмотрим два самых распространенных способа:

И ещё один вариант, который идентичен предыдущему.

С обработчиком «on()» лучше ознакомиться отдельно, так как он несет в себе много полезного функционала. Например, возможность указать через пробел несколько событий к которым будет применяться действие, делегировать события на дочерние элементы, а так же он полезен если необходимо повесить событие на динамически добавляемые элементы, которых изначально нет на странице.

О том, как не нужно работать с JavaScript и jQuery

Микулич Евгений

Дата последнего входа: более года назад

Начать хочется, с казалось бы, элементарной вещи – концепции разделения представления логики того или иного скрипта(компонента) и его представления. Битрикс представляет возможность работать с шаблонами компонентов, не трогая их логичесую реализацию, и более того дает возможность «допилить» ее путем создания некоторых файлов типа «result_modifier.php». Казалось бы все элементарно, и большинство разработчиков пользуется этой замечательной вещью в отношении HTML и PHP. Бывают конечно исключения и в практике приходится встречать вызовы одного компонента в шаблоне другого, а в шаблоне второго вызов еще одного, а в шаблоне третьего еще двух компонентов, в шаблоне которых вызывается пятый но с разными входными параметрами (Типовое решение «Медицинских учреждений»). Согласитесь, если это не комплексный компонент, то работать с таким кодом, и дорабатывать его очень трудно и тяжело. Ситуация с JavaScript не настолько катастрофична, как в предыдущем примере, но на мой взгляд если уж разделять логику и представление – то быть последовательным до конца и включить в эту концепцию JavaScript в том числе.

От человеческой лени или незнания или каких-либо других причин приходится сталкиваться со следующим мнением «Я так всегда делал», «Это надежно», «Так делали мои деды и прадеды». В пору вспоминается анекдот: «В комнате муха долбиться в окно, желая вылететь наружу. С другой стороны к ней подлетает другая муха и говорит: «Ты чего долбишься? Вон же форточка открыта». На что первая ей отвечает: «Нет, мой отец бился, мой дед бился, мой прадед бился в это окно и я биться буду.».». Есть несколько причин не делать так, как ты делал когда-то, и в этой статье я постараюсь осветить некоторые из них.

Атрибуты oncklick, onchange, onmouseover и им подобные в HTML
Часто в чужом коде приходится встречаться с таким примером:

Теперь рассмотрим почему так делать не нужно:


1. Концепция разделения программирования и представление информации. Битрикс дает замечательную возможность перенести весь свой код в файл script.js, который автоматом подключается и очень удбен для разработки. Мое мнение — HTML должен быть чистый, со вкраплениями PHP и если возможности самого языка JavaScript а тем более популярного Framework jQuery позволяют не добавлять в HTML ничего не нужного, то этим стоит пользоваться. Сегодня мы сделали так, через месяц по другому, еще через неделю пришлось изменить логику и что то уже не приходит, какие то данные изменились и надо везде править изменения.
2. Происходит элементарное затирание объекта MouseEvent, который передается всегда в любом событии. Таким образом передавая параметры в нашу фукцию getData(this, мы просто лишаем себя многих возможностей, в том числе тмены стандартного обработчика события, но о нем еще поговорим ниже. Вот пример, который показывает объект MouseEvent, который содержит всю информацию о нажатии, и поверьте там есть все и даже больше того чего нужно:

Таким образом, если мы передадим любой параметр в фукцию, то затрем параметр по умолчанию, что не есть хорошо. Этого можно избежать если все свои данные, необходимые для обработки, вы передадите в атрибут класса, или добавите элементы в DOM документ которые будут содержать эти данные опять же в своих классах. Если вы используете HTML 5, то для этого теперь есть атрибут data-<название>=”значение”, при небольшом ухищрении этот тег будет работать и в старых IE. Вариантов передать данные в HTML масса. В последствии многие просто не хотят или ленятся эти данные получать и вытаскивать из структуры DOM. Что тоже никак не оправдывает такой подход. С одной стороны использование атрибутов событий в HTML дает нам небольшое преимущество в скорости и простоте, но это старый век, и так делать некрасиво, тем более что зачастую, сами того не подозревая, нам нужны возможности объекта MouseEvent.

3. О «return false». Вообще в парадигме программирования функция возвращает либо результат операций, либо результат того что операции были выполнены успешно, либо результат того, что они были выполнены с ошибками или вовсе не выполнены. Уж точно возвращение лжи не было придумано для того чтобы ссылка не отрабатывала по событию click. Тем более часто бывает нужно что-то вернуть из функции, а мы уже себе поставили ограничение, и наша функция должна возвращает только ложь, чтобы не сработал стандартный обработчик тега . Некоторые идут дальше и не используют атрибут href (что не верно, так как при сбое в скриптах или отключенной поддержке скриптов пользователь никуда не попадет), либо затирают или удаляют атрибут href в самом скрипте, что тоже является не красивым и приводит к той же проблеме сбоя скрипта и пользователь никуда не попадет.
Вернемся к нашему объекту MouseEvent. А ведь в нем уже все есть. Для JavaScript не нужно ничего дописывать, так как вышеприведенных примерах мы и так переопределили обработчик события click. А вот для jQuery это делается следующим образом:

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

Методы click(), bind(), live()

Если у нас на страничке очень много однотипных ссылок и нам нужно обработать их событие onclick, то так делать категорически не нужно:

Если же информация на страницу подгружается технологией ajax, то используя метод bind() новые тэги или группы тегов не будут откликаться по вашему обработчику, для этого используется метод live():

Теперь все элементы структуры DOM в том числе и вновь добавленные будут закреплены за данным обработчиком события.
Примечание: Будте аккуратны используя данные методы. В сарых IE они не работают при использовании jQuery версии ниже 1.4.2.
Самый надежный метод регестрирования события on() так как он не меняется в jQuery от версии к версии и на его основе создаются другие методы, он является как бы родителем:

Часто я сталкиваюсь с высказываниями «Нужно чтобы все работало быстро, минимум запросов, оптимальное использование PHP». И часто вижу на сайтах, что сервер быстро сгенерировал страницы, выполнил запросы, а страница все еще не готова, потому что грузятся скрипты. По хорошему нужно было бы написать целый раздел на эту тему, а не подтему одной статьи, но когда я вижу следующий код, то понимаю, что человек не совсем понимает для чего он использует jQuery:

При загрузке страницы jQuery находит все теги с классом «links». Далее ко всем этим ссылкам добаляется параметр ajax. Создается впечатление что пользователь нажмет на все эти ссылки разом. Пользователь всегда нажмет на одну ссылку, поэтому целесообразний использовать следующий код:

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

В переменную а всё кладется как положено, но в переменню b каждую итерацию кладутся одни и те же данные, но с огромными потерями производительности, то есть на каждый чих мы ищем в структуре документа теги с классом someClass. Имя возможность их сохранить мы все равно дергаем DOM (а если количество строк в документе 5000?). Необходимо выносить такие вещи из тела функции:

Первый вариант отработает по загрузке и готовности структуры документа, второй вариант — функция будет вызвана сразу же как только она встретится. К сожалению второй вариант и возможность битрикса с подключением файла script.js не совместим, так как этот файл подключается методом AddHeadScript(), а это значит, что она будет вызвана в head, до построения дерева. Второй вариант предпочтителено размещать в конце документа.

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

Работаем с событиями в jQuery

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

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

В данном уроке будут раскрыты следующие темы:

  • Что такое событие?
  • Работа с событиями
  • Простой обработчик события
  • Короткие методы для связывания общих событий
  • Доступ к элементам из обработчика события
  • Получение дополнительной информации о событии
  • Остановка действий по умолчанию и распространение событий
  • Сброс обработчика события
  • Принудительная генерация события

Что такое событие?

Событие в JavaScript (и jQuery) генерируется, когда что-то происходит с элементом на странице. В список общих событий входят:

click Генерируется, когда пользователь нажимает на элементе кнопку мыши dblclick Генерируется, когда пользователь делает двойной щелчок кнопкой мыши на элементе mouseover Генерируется, когда пользователь перемещает указатель мыши на элемент load Генерируется после того, как элемент, например, изображение, полностью загружен submit Генерируется, когда происходит отправка формы (данное событие генерируется только для элементов form )

Работаем с событиями

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

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

Затем, когда происходит событие, ваша функция-обработчик автоматически и событие обрабатывается так, как требуется.

Простой пример

Следующий пример показывает, как создать простой обработчик события и привязать его к событию click кнопки формы:

Если нажать на кнопку на странице, будет выведено окно сообщения с надписью «Всем — привет!».

Короткие методы для связывания общих событий

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

click( functionName ) Эквивалентно вызову bind( ‘click’, functionName ) dblclick( functionName ) Эквивалентно вызову bind( ‘dblclick’, functionName ) load( functionName ) Эквивалентно вызову bind( ‘load’, functionName )

Например, вы можете переписать вызов метода bind() в выше приведённом примере следующим образом:

Полный список коротких методов можно найти в документации jQuery по методу bind() .

Доступ к элементам из обработчика событий

Когда событие вызывает функцию-обработчик, вы можете получить доступ к элементу как к объекту DOM из функции-обработчика с помощью ключевого слова this . Это означает, что вы можете получить больше информации об элементе, для которого сгенерировано событие, можете манипулировать данным элементом и так далее.

Следующий пример создаёт пульсации кнопки (плавно затухает и плавно высвечивается снова) при нажатии на неё. Чтобы выполнить поставленную задачу, обработчик события получает доступ к объекту нажатой кнопки с помощью this , оборачивает его объектом jQuery, а затем вызывает методы jQuery fadeOut() и fadeIn() для организации пульсирования кнопки:

Цукерберг рекомендует:  Когда работать в офисе — это круто

Получение дополнительной информации о событии

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

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

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

Выше приведённый скрипт использует три свойства 3 объекта event :

timeStamp Время, когда произошло событие pageX Координата X указателя мыши в момент нажатия на кнопку, по отношению к левому верхнему углу документа pageY Координата Y указателя мыши в момент нажатия на кнопку, по отношению к левому верхнему углу документа

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

Остановка действий по умолчанию и распространение событий

События в JavaScript имеют пару особенностей, о которых надо упомянуть:

  • Действия по умолчанию. многие события имеют действия по умолчанию. Например, если пользователь нажмет на ссылку, то по умолчанию событие click для ссылки открывает ссылку.
  • Распространение событий. Также известно как «всплытие» события, происходит тогда, когда вы привязываете обработчик к одному и тому же событию для элемента и его родителя. Например, вы привязываете обработчик к событию click для ссылки, и привязываете другой обработчик к событию click для параграфа, который содержит ссылку. Когда пользователь нажимает ссылку, обработчик события click ссылки запускается первым, а затем событие «всплывает» к родительскому параграфу, вызывая срабатывание его обработчика события click .

Часто нужно предотвращать запуск действий по умолчанию и/или распространение событий. Например, если установлен обработчик события click для ссылки, который нужен для проверки правильности заполнения формы перед тем как покинуть страницу, то нужно предотвратить переход по ссылке, который выполняется по умолчанию.

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

Объект jQuery event даёт вам пару методов для того, чтобы остановить такое поведение программы:


preventDefault() Останавливает выполнение действий по умолчанию stopPropagation() Останавливает «всплытие» события к родительскому элементу

Следующий пример открывает ссылку в новом окне, когда на неё нажимают, и использует метод preventDefault() чтобы остановить открытие ссылки в текущем окне:

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

Сброс обработчика события

Если вы хотите удалить обработчик события из элемента, вызовите метод unbind() . Для удаления всех обработчиков события:

Для удаления обработчика заданного события:

Принудительная генерация события

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

Метод jQuery trigger() генерирует определённое событие для выбранного элемента (или элементов). Имя события нужно передать trigger() в триггер в качестве аргумента.

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

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

Резюме

В данном уроке мы рассмотрели, как работать с событиями в jQuery:

  • Что такое событие?
  • Работа с событиями
  • Простой обработчик события
  • Короткие методы для связывания общих событий
  • Доступ к элементам из обработчика события
  • Получение дополнительной информации о событии
  • Остановка действий по умолчанию и распространение событий
  • Сброс обработчика события
  • Принудительная генерация события

События являются очень мощным и полезным инструментом, а в jQuery многое сделано для того, чтобы облегчить работу с ними.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.elated.com/articles/jquery-events/
Перевел: Сергей Фастунов
Урок создан: 10 Августа 2010
Просмотров: 99586
Правила перепечатки

5 последних уроков рубрики «jQuery»

Анимация набора текста на jQuery

Сегодня мы бы хотели вам рассказать о библиотеке TypeIt — бесплатном jQuery плагине. С её помощью можно имитировать набор текста. Если всё настроить правильно, то можно добиться очень реалистичного эффекта.

Временная шкала на jQuery

jQuery плагин для создания временной шкалы.

Заметка: Перезагрузка и редирект на JavaScript

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

Рисуем диаграмму Ганта

jQuery плагин для создания диаграммы Ганта.

AJAX и PHP: загрузка файла

Пример того как осуществить загрузку файла через PHP и jQuery ajax.

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

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

Событие – это «реакция» браузера на действие пользователя. Например, когда пользователь на странице нажимает на кнопку, браузер в соответствии с ним генерирует событие (в данном случае click ). Более подробно узнать, как это происходит можно в статье JavaScript — Знакомство с событиями.

Для работы с событиями в сценариях JavaScript браузер предоставляет API (например, функцию addEventListener ). Используя эту функцию, вы можете указать код, который необходимо выполнить, когда браузер для указанного элемента будет генерировать указанное событие.

Обработка событий с помощью методов jQuery

Перед тем как переходить к добавлению элементам обработчиков событий, эти элементы сначала необходимо получить. Узнать о том, как найти нужные элементы на странице можно в статье jQuery — Выбор элементов.

В jQuery повесить событие (слушатель событий) на определённый элемент можно с помощью функций on и one , а также кратких записей on .

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

Например, добавим с помощью функции on событие click для всех элементов с классом btn :

Вышеприведённый код, записанный с использованием короткой записи функции on :

Дополнительная информация о событии

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

Пространство имён

В jQuery после указания имени события вы можете ещё дополнительно указать пространство имён.

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

Также с его помощью очень просто удалять определённые события:

Описание и примеры использования функций trigger и off рассматриваются в статье немного ниже.

Передача дополнительных данных в обработчик

При необходимости вы можете передать данные в обработчик события (посредством указания дополнительного аргумента в функции on ). Доступ к переданным данным внутри обработчика осуществляется через объект Event .

Осуществляется это так (пример):

Как повесить несколько событий на один элемент

Пример использования одного обработчика для нескольких (2 или более) событий:

Для каждого события своя функция:


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

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

Программный вызов события

Для вызова события из кода в jQuery есть 2 метода:

  • trigger — вызывает указанное событие у элемента.
  • triggerHandler — вызывает обработчик события, при этом само событие не происходит.

jQuery — Событие загрузки страницы (ready)

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

Самая короткая запись события загрузки страницы в jQuery выглядит так:

Но, можно использовать и более длинную запись:

jQuery — Событие загрузки (load)

Событие load браузер генерирует элементу, когда он и все вложенные в него элементы были полностью загружены. Данное событие предназначено только для элементов, в которых присутствует URL: image , script , iframe и window .

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

Например, выведем сообщение в консоль, когда указанное изображение будет загружено:

jQuery — События мыши

В jQuery для отслеживания действий мыши наиболее часто используют следующие события:

  • mousedown
  • mouseup
  • click
  • mousemove
  • wheel
  • hover
  • mouseenter
  • mouseover
  • mouseleave
  • mouseout

jQuery — Событие клик (click)

Событие click является сложным событием, оно возникает после генерирования событий mousedown и mouseup . Событие mousedown возникает, когда указатель находится над элементом и кнопка мыши нажата. Событие mouseup происходит, когда указатель находится над элементом и кнопка мыши отпущена. Событие click генерируется, когда курсор находится над элементом, и клавиша мыши нажата и отпущена. Эти события могут получать любые HTML элементы.

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

Например, повесим событие onclick на все элементы с классом btn :

Краткая запись события по клику:

Например, разберем, как можно скрыть блок через некоторое время после события click :

jQuery — Событие при наведении (hover)

Событие при поднесении курсора является сложным и состоит из 2 событий:

  • вхождения (mouseenter, mouseover);
  • покидания (mouseleave, mouseout).

События mouseenter и mouseleave в jQuery отличаются от mouseover и mouseout только тем, что они не возникают когда курсор соответственно входит и покидает внутренние элементы прослушиваемого элемента. Другими словами события mouseover и mouseout всплывают, а mouseenter и mouseleave – нет.

Например, изменим цвет элемента списка при поднесении к нему курсора:

Те же самые действия, но использованиям mouseover и mouseout :

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

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

Вместо использования mouseenter и mouseleave можно использовать событие hover .

Например, перепишем вышеприведённый пример, используя hover :

При использовании события hover в jQuery, первый обработчик используется для задания действий при вхождении курсора в элемент ( mouseenter ), а второй — при покидании ( mouseleave ).

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

jQuery — Событие движения мыши

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

jQuery — Событие колёсика мыши (wheel)

Прослушивание события прокрутки колёсика (wheel) мышки можно осуществить так:

Данное событие в отличие от scroll генерируется браузером только для колёсика мышки, при этом неважно прокручивается элемент или нет, т.е. с ним можно работать на элементах с overflow , равным hidden . Еще одно отличие заключается в том, что wheel генерируется до прокрутки, а scroll — после неё.

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

При нажатии клавиши клавиатуры браузер генерирует события в следующем порядке:

  • keydown (клавиша нажата, но ещё не отпущена);
  • keypress (событие генерируется для букв, цифр и других клавиш, за исключением управляющих) – предназначено для того чтобы получить код символа (события keydown и keyup позволяют узнать только о коде клавиши, но не символа);
  • keyup (генерируется браузером при отпускании клавиши).

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

Пример, в котором показано, как можно прослушать событие keypress и узнать, нажато ли указанное сочетание клавиш:

Пример, как можно прослушать сочетание клавиш Ctrl+Enter :

Пример, с использованием событий keydown и keyup :

jQuery – События элементов формы

В jQuery можно выделить следующие события для элементов формы и не только:


  • focus (focusin)
  • blur (focusout)
  • change
  • input (для текстовых элементов формы)
  • select
  • submit

jQuery — События получения и потери фокуса

Событие focus посылается элементу, когда он получает фокус. Данное событие генерируется для элементов input , select и ссылок ( a href=». » ), а также любых других элементов, у которых установлено свойство tabindex . Получение элементом фокуса обычно осуществляется посредством клика или нажатия клавиши Tab на клавиатуре. Событие focus не всплывает.

Кроме focus есть ещё похожее событие, называется оно focusin . В отличие от focus данное событие всплывает, и оно может, например, использоваться для обнаружения события фокуса родительскими элементами.

Событие blur посылается элементу, когда он теряет фокус. Так же как и focus , событие blur имеет похожее событие focusout . Данное событие отличается от blur тем, что оно может всплывать. Это возможность можно использовать, например, для получения его на родительских элементах, а не только на том элементе, который его вызвал ( target ).

Например, при получении элементом div события фокуса установим ему фон оранжевого цвета:

Точно такое же выполнить с помощью событий focus и blur не получится, т.к. они не всплывают:

jQuery — Событие изменения (change)

Событие change предназначено для регистрации изменения значения элементов input , textarea и select . Для элементов select , checkboxes , и radio кнопок данное событие возникает сразу (т.е. как только пользователь делает какой-то выбор). Но для других элементов данное событие не будет происходить до тех пор, пока этот элемент не потеряет фокус.

Пример использования события change для слежения за состоянием элемента checkbox . Доступность кнопки будет определять в зависимости от того в каком состоянии ( checked или нет) находиться флажок:

Пример, в котором рассмотрим, как получить значение элемента select при его изменении:

Пример, в котором рассмотрим, как получить все выбранные элементы select при его изменении:

Пример программного вызова события change для элемента select :

Пример использования события изменения change для получения значения элемента input :

Но кроме события change есть ещё событие input для текстовых элементов. Данное событие в отличие от change генерируется сразу, а не после того как данный элемент потеряет фокус.

Пример, использования события ввода для получения значения элемента input :

Пример, в котором представлен один из способов получения значения элемента textarea :

Пример, в котором рассмотрим, как с помощью события change получить значение выбранного элемента input с type , равным radio :

jQuery — Событие выбора (select)

Событие выбора select генерируется браузером, когда пользователь внутри элементов input с type=»text» или textarea выделяет текст.

jQuery – Событие отправки формы (submit)

Событие submit возникает у элемента, когда пользователь пытается отправить форму. Данное событие может быть добавлено только к элементам form .

Пример, использования события submit :

Программный вызов отправки формы:

jQuery — Событие прокрутки (scroll)

Для отслеживания состояния скроллинга в jQuery используется событие scroll .

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

jQuery — Событие изменения размеров окна (resize)

Для прослушивания события изменения окна браузера используется resize :

Например, создадим обработчик, который будет при изменении окна браузера выводить в конец страницы её ширину и высоту:

jQuery — Отмена стандартного поведения события

Некоторые элементы в HTML имеют стандартное поведение. Например, когда пользователь нажимает на ссылку, он переходит по адресу указанному в атрибуте href . Если вам это действие не нужно, то его можно отменить. Для отмены стандартного поведения необходимо вызвать в обработчике этого события метод preventDefault объекта event .

Например, отменим стандартное поведение всех ссылок на странице, имеющих класс service :

Что такое всплытие и как его остановить

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

В jQuery бывают сценарии, когда в представленной цепочке у какого-нибудь элемента то же есть обработчик для этого события, который выполнять не нужно. И чтобы это событие не распространилось на этот элемент, его необходимо остановить. Для этого в обработчике нужного элемента необходимо вызвать метод stopPropagation объекта event . После вызова этого метода событие остановится, и не будет всплывать.

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

Цукерберг рекомендует:  Вакансии Веб-сайт SafeOrders.

В данном случае если не указывать метод stopPropagation , то при поднесении курсора к элементу span с классом mark данное событие возникнет не только у него, но и у всех его родительских элементов. А это в этом примере приведёт к тому, что изменится цвет не только текста, заключенного в span , но и всего абзаца.

Если вам необходимо отменить стандартное поведение браузера и остановить всплытие события, то в jQuery вместо вызова двух этих методов можно просто вернуть в качестве результата функции значение false .

Добавление событий к динамически созданным объектам

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

Это действие можно осуществить благодаря тому, что событие всплывает, и, следовательно, возникает у всех предков этого элемента. А объект, до которого всплывают все события на странице, является document . Поэтому в большинстве случаев выбирают именно его. После этого зная селектор, функция on может программно отобрать среди элементов (элемента, который вызвал это событие ( target ) и всех его предков включая родителя) те, которые соответствуют ему. И затем для всех отобранных элементов выполнить указанный в функции on обработчик. Действия, посредством которых обработка события переносится на другой элемент (предок), называется в jQuery ещё процессом делегирования события.

Например, добавим событие к элементу, которого ещё нет на странице:

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

Например, запретим в комментариях переходить по внешним ссылкам (такие действия будем перенаправлять на страницу away):

jQuery — Удалить обработчик события

Удаление обработчиков события осуществляется с помощью метода off . При этом с помощью него можно удалить только те обработчики, которые добавлены посредством метода on .

Вызов метода off без аргументов снимет у указанных элементов все добавленные к ним обработчики событий.

Например, отключим все обработчики у элементов с классом link:

Например, удалим событие click у всех элементов с классом link :


Специальный селектор ( ** ) позволяет удалить только делегированные события с сохранением не делегированных:

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

Удалить все обработчики openModal делегированного события click в пространстве имён modal для элементов с классом show :

Создание пользовательского события

Для создания пользовательских событий в jQuery используются методы on и trigger .

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

JavaScript: в callback функции теряется контекст. Как это обойти?

Разбираюсь значит с загрузкой данных с сервера и событийной моделью в JavaScript.

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

Код примерно такой:

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

Uncaught exception: TypeError: ‘this.calculate’ is not a function

Ошибка в FireFox:

TypeError: this.calculate is not a function initNext

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

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

Типы событий

На заре развития Всемирной паутины веб-разработчикам приходилось иметь дело лишь с небольшим количеством событий: «load», «click», «mouseover» и другими. Эти довольно старые типы событий хорошо поддерживаются всеми браузерами. По мере развития веб-платформы в нее были включены более мощные прикладные интерфейсы, а количество событий существенно увеличилось. Не существует стандарта, который определял бы полный набор событий, и количество поддерживаемых событий продолжает быстро увеличиваться. Эти новые события определяются в следующих двух источниках:

Спецификация «DOM Level 3 Events», которая после долгих лет застоя стала активно разрабатываться под эгидой консорциума W3C.

Множество новых прикладных интерфейсов в спецификации HTML5 (и в связанных с ней дополнительных спецификациях) определяют новые события, используемые, например, для управления историей посещений, механизмом drag-and-drop (перетащил и бросил), обмена сообщениями между документами и проигрывания аудио- и видеороликов.

Обратите внимание, что многие из этих новых типов событий пока еще не получили широкой поддержки и определяются стандартами, которые еще находятся на стадии проектирования. События, которые вам чаще всего придется использовать в своих веб-приложениях, обычно будут относиться к категории давно существующих и поддерживаемых всеми браузерами: это события для работы с мышью, с клавиатурой, с HTML-формами и с объектом Window. Эти события мы и рассмотрим.

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

Большинству веб-приложений совершенно необходимо, чтобы веб-браузер извещал их о моменте, когда закончится загрузка документа и он будет готов для выполнения операций над ним. Этой цели служит событие load в объекте Window. Событие load возбуждается только после того, как документ и все его изображения будут полностью загружены. Однако обычно сценарии можно запускать сразу после синтаксического анализа документа, до того как будут загружены изображения. Можно существенно сократить время запуска веб-приложения, если начинать выполнение сценариев по событиям, отличным от load.

Событие DOMContentLoaded возбуждается, как только документ будет загружен, разобран синтаксическим анализатором, и будут выполнены все отложенные сценарии. К этому моменту изображения и сценарии с атрибутом async могут продолжать загружаться, но сам документ уже будет готов к выполнению операций. Это событие впервые было введено в Firefox и впоследствии заимствовано всеми другими производителями браузеров, включая корпорацию Microsoft, которая добавила поддержку этого события в IE9. Несмотря на приставку DOM в имени, это событие не является частью стандарта модели событий DOM Level 3 Events, но оно стандартизовано спецификацией HTML5.

В ходе загрузки документа изменяется значение свойства document.readyState. Каждое изменение значения этого свойства в IE сопровождается событием readystatechange в объекте Document, благодаря чему в IE это событие можно использовать для определения момента появления состояния complete. Спецификация HTML5 стандартизует событие readystatechange, но предписывает возбуждать его непосредственно перед событием load, поэтому не совсем понятно, в чем заключается преимущество события readystatechange перед load.

В примере ниже определяется функция whenReady(). Функция, передаваемая функции whenReady(), вызывается (как метод объекта Document) сразу, как только документ будет готов к выполнению операций. whenReady() ожидает появления событий DOMContentLoaded и readystatechange и использует событие load только как запасной вариант, на случай если она будет задействована в старых браузерах, не поддерживающих первые два события. Функция whenReady() будет использоваться в некоторых сценариях, следующих далее:

События мыши

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

События мыши JavaScript

Тип Описание
click Высокоуровневое событие, возбуждаемое, когда пользователь нажимает и отпускает кнопку мыши или иным образом активирует элемент.
contextmenu Отменяемое событие, возбуждаемое перед выводом контекстного меню. Текущие браузеры выводят контекстное меню по щелчку правой кнопки мыши, поэтому данное событие можно также использовать как событие click.
dblclick Возбуждается, когда пользователь выполняет двойной щелчок.
mousedown Возбуждается, когда пользователь нажимает кнопку мыши.
mouseup Возбуждается, когда пользователь отпускает кнопку мыши.
mousemove Возбуждается, когда пользователь перемещает указатель мыши.
mouseover Возбуждается, когда указатель мыши помещается над элементом. Свойство relatedTarget (или fromElement в IE) определяет элемент, с которого был перемещен указатель мыши.
mouseout Возбуждается, когда указатель мыши покидает элемент. Свойство relatedTarget (или toElement в IE) определяет элемент, на который был перемещен указатель мыши.
mouseenter Подобно mouseover, но не всплывает. Впервые появилось в IE и было стандартизовано в HTML5, но пока поддерживается не всеми браузерами.
mouseleave Подобно mouseout, но не всплывает. Впервые появилось в IE и было стандартизовано в HTML5, но пока поддерживается не всеми браузерами.

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

Свойства altKey, ctrlKey, metaKey и shiftKey определяют состояния различных клавиш-модификаторов, которые могли удерживаться в нажатом состоянии в момент события: с их помощью можно отличать простой щелчок от щелчка с нажатой клавишей Shift, например.

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

Некоторые браузеры возбуждают событие click только в случае щелчка левой кнопкой. Поэтому, если потребуется обрабатывать щелчки другими кнопками, следует использовать события mousedown и mouseup. Событие contextmenu обычно сигнализирует о том, что был выполнен щелчок правой кнопкой, но, как отмечалось выше, в обработчиках этого события не всегда бывает возможным предотвратить появление контекстного меню.

В примере ниже демонстрируется функция drag(), которая при вызове из обработчика события mousedown позволяет пользователю перетаскивать мышью абсолютно позиционированные элементы документа. Функция drag() работает с обеими моделями событий, DOM и IE.

Функция drag() принимает два аргумента. Первый — перетаскиваемый элемент. Это может быть элемент, в котором возникло событие mousedown, и содержащий его элемент (например, можно дать пользователю возможность ухватить мышью элемент, который выглядит как заголовок окна, и перетащить содержащий его элемент, который выглядит как окно). Однако в любом случае это должен быть элемент документа, абсолютно позиционированный с помощью CSS-атрибута position. Второй аргумент — объект события, полученный с событием mousedown:

Следующий фрагмент демонстрирует порядок использования функции drag() в HTML-файле:

Самым важным здесь является атрибут onmousedown во вложенном элементе

События ввода текста

Браузеры поддерживают три старых события ввода с клавиатуры. События keydown и keyup являются низкоуровневыми событиями и рассматриваются в следующем разделе. Однако событие keypress является высокоуровневым, сообщающим, что был введен печатаемый символ.

Проект спецификации DOM Level 3 Events определяет более обобщенное событие textinput, генерируемое в ответ на ввод текста, независимо от того, каким способом он был введен.

С предлагаемым событием textinput и реализованным в настоящее время событием textInput передается простой объект события, имеющий свойство data, хранящее введенный текст. (Другое предлагаемое спецификацией свойство, inputMethod, должно определять источник ввода, но оно пока не реализовано.) В случае ввода с клавиатуры свойство data обычно будет содержать единственный символ, но при вводе из других источников в нем может содержаться множество символов.

Объект события, передаваемый с событием keypress, имеет более сложную организацию. Событие keypress представляет ввод единственного символа. Этот символ содержится в объекте события в виде числового значения кодового пункта Юникода и, чтобы преобразовать его в строку, необходимо использовать метод String.fromCharCode(). В большинстве браузеров кодовый пункт введенного символа сохраняется в свойстве keyCode объекта события. Однако по историческим причинам в Firefox вместо него используется свойство charCode.

В большинстве браузеров событие keypress возбуждается только при вводе печатаемого символа. Однако в Firefox событие keypress возбуждается также для непечатаемых символов. Чтобы отличить эти два случая (и проигнорировать непечатаемые символы), можно проверить, существует ли свойство charCode объекта события и содержит ли оно значение 0.

События textinput, textInput и keypress можно отменить, чтобы предотвратить ввод символа. То есть эти события можно использовать для фильтрации ввода. Например, можно предотвратить ввод алфавитных символов в поле, предназначенное для ввода числовых данных.

В примере ниже демонстрируется модуль на языке JavaScript, реализующий такого рода фильтрацию. Он отыскивает элементы с дополнительным (нестандартным) атрибутом data-allowed-chars. Регистрирует обработчики событий textinput, textInput и keypress для всех найденных элементов и ограничивает возможность ввода символами регулярного выражения, заданным в атрибуте data-allowed-chars:

Ниже показан образец разметки HTML, использующей этот модуль:

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

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

Браузеры также реализуют событие input, которое возбуждается после вставки текста в элемент. Это событие нельзя отменить и соответствующий ему объект события не содержит информации о вставленном тексте — оно просто извещает о том, что текстовое содержимое элемента изменилось. Если, к примеру, потребуется обеспечить ввод только символов в верхнем регистре, можно определить обработчик события input, как показано ниже:

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

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

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

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

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

Подобно объектам событий мыши, объекты событий клавиатуры имеют свойства altKey, ctrlKey, metaKey и shiftKey, которые получают значение true, если в момент возникновения события удерживалась нажатой соответствующая клавиша-модификатор.

События keydown и keyup, а также свойство keyCode используются уже более десяти лет, но они так и не были стандартизованы. Проект стандарта DOM Level 3 Events стандартизует типы keydown и keyup событий, но не стандартизует свойство keyCode. Вместо этого он определяет новое свойство key, которое должно содержать название клавиши в виде строки. Если клавиша соответствует печатаемому символу, свойство key должно содержать этот печатаемый символ. Для функциональных клавиш свойство key должно содержать такие значения, как F2, Home или Left.

На момент написания этих строк свойство key, определяемое стандартом DOM Level 3 Events, еще не было реализовано ни в одном из браузеров. Однако браузеры на базе механизма Webkit, Safari и Chrome определяют в объектах этих событий свойство keyIdentifier. Для функциональных клавиш, подобно свойству key, свойство keyIdentifier содержит не число, а строку с именем клавиши, таким как Shift или Enter. Для клавиш, соответствующих печатаемым символам, это свойство содержит менее удобное в использовании строковое представление кодового пункта Юникода символа. Например, клавише A соответствует значение U+0041.

В примере ниже определяется класс Keymap, который отображает идентификаторы комбинаций клавиш, такие как PageUp, Alt_Z и ctrl+alt+shift+F5 в функции на языке JavaScript, вызываемые в ответ на нажатия этих комбинаций. Определения привязок клавиш передаются конструктору Keymap() в форме объекта JavaScript, имена свойств которого соответствуют идентификаторам комбинаций клавиш, а значения этих свойств содержат ссылки на функции-обработчики. Добавление и удаление привязок осуществляется с помощью методов bind() и unbind().

Устанавливается объект Keymap в HTML-элемент (обычно в объект Document) с помощью метода install(). При установке объекта Keymap в этом элементе регистрируется обработчик события keydown. Каждый раз, когда нажимается клавиша, обработчик проверяет наличие функции, соответствующей этой комбинации. Если функция существует, она вызывается.

Обработчик события keydown использует свойство key, определяемое стандартом «DOM Level 3 Events», если оно существует. В противном случае он пытается использовать Webkit-свойство keyIdentifier. И как запасной вариант, обработчик использует нестандартное свойство keyCode:

Ниже показан пример использования объекта Keymap:

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих