pointer events none что это
События указателя
Бо́льшая часть современного веб-контента предполагает, что указывающим устройством пользователя является мышь. Но поскольку многие устройства поддерживают другие типы указателей, таких как перо/стилус или сенсорная поверхность, возникает необходимость в расширении существующих событий указывающих устройств. Эту потребность удовлетворяют События указателя.
События указателя – это события DOM, которые вызываются для указывающего устройства. Они предназначены для создания единой модели обработки действий мыши, пера/стилуса или касания (одним или несколькими пальцами).
Указывающее устройство – это устройство, способное нацеливаться на определённый набор координат экрана. Наличие единой модели событий для указывающих устройств позволяет разработчикам проще создавать веб-сайты и приложения, а пользователям обеспечивает удобство использования вне зависимости от устройства.
Терминология
Интерфейсы
Следующие подразделы содержат краткое описание каждого интерфейса и свойства.
Интерфейс PointerEvent
Типы событий и Глобальные Обработчики Событий
Событие | Обработчик события | Описание |
---|---|---|
pointerover | onpointerover (en-US) | Вызывается, когда указатель появляется в пределах элемента (его теста попадания). |
pointerenter | onpointerenter (en-US) | Вызывается, когда указатель перемещается в пределы элемента (его теста попадания) или одного из его потомков, в том числе в результате события pointerdown с устройства, которе не поддерживает наведение «hover» (смотрите pointerdown ). |
pointerdown | onpointerdown (en-US) | Вызывается, когда указатель принимает состояние активных кнопок. |
pointermove | onpointermove (en-US) | Вызывается, когда изменяются координаты указателя. Это событие также используется, если изменение состояния указателя нельзя сообщить с помощью других событий. |
pointerup | onpointerup (en-US) | Вызывается, когда указатель теряет состояние активных кнопок. |
pointercancel | onpointercancel (en-US) | Браузер вызывает это событие, если приходит к выводу, что указывающее устройство больше не сможет генерировать события (например, если устройство деактивировано). |
pointerout | onpointerout (en-US) | Вызывается по нескольким причинам, в том числе: когда указывающее устройство перемещается за пределы элемента (его теста попадания); запуск события pointerup для устройства, которое не поддерживает наведение «hover»; после запуска события pointercancel ; когда перо покидает область обнаружения планшетом наведения указателя. |
pointerleave | onpointerleave (en-US) | Вызывается, когда указывающее устройство перемещается за пределы элемента (его теста попадания). Для устройств, подобных перу, это событие вызывается, когда перо покидает область обнаружения планшетом наведения указателя. |
gotpointercapture | ongotpointercapture (en-US) | Вызывается, когда элемент получает захват указывающего устройства. |
lostpointercapture | onlostpointercapture (en-US) | Запускается после того, как указывающее устройство потеряло захват. |
Расширения элемента
Существует три расширения интерфейса Element :
setPointerCapture() (en-US) Определяет определённый элемент в качестве цели захвата для будущих событий указателя. releasePointerCapture() (en-US) Этот метод освобождает (прекращает) захватывание указывающим устройством, которое ранее было установлено для определённого события указателя.
Расширение навигатора
Свойство Navigator.maxTouchPoints (en-US) используется для определения максимального количества одновременных точек касания, которые поддерживаются в каждый момент времени.
Примеры
Этот раздел содержит примеры базового использования интерфейсов событий указывающего устройства.
Назначение обработчиков событий
В этом примере определённому элементу назначаются обработчики каждого типа события.
Свойства события
Этот пример демонстрирует доступ ко всем свойствам события касания.
Определение Основного Указателя
В некоторых сценариях может быть несколько указывающих устройств (например, устройство с сенсорным экраном и мышкой) или указывающее устройство, поддерживающее несколько контактных точек (например, сенсорный экран, который поддерживает касания несколькими пальцами). Приложение может использовать свойство isPrimary (en-US) для определения главного указателя среди набора активных точек каждого указателя. Если будет решено поддерживать только основной указатель, в приложении можно игнорировать все события указателя, не являющегося главным.
У мышки может только один указатель, поэтому он всегда будет главным. Для сенсорного ввода указатель считается главным, если при этом нет других активных касаний. Для ввода пером или стилусом, указатель считается главным, если при этом нет касаний другими перьями.
Определение состояний кнопок
Некоторые указывающие устройства, такие как мышь или перо, поддерживают несколько кнопок, и эти кнопки могут нажиматься одновременно. Например, нажатие кнопки, когда другая кнопка на устройстве уже нажата.
В следующей таблице приведены значения button и buttons для различных состояний кнопок устройства.
Состояние кнопок устройства | button | buttons |
---|---|---|
С последнего события не было ни нажатия кнопок, ни касания пера | -1 | — |
Мышь перемещается без нажатых кнопок. Перо перемещается над планшетом в режиме «hover» без нажатых кнопок | — | 0 |
Левая кнопка мыши, Касание пальцем, Касание пером | 0 | 1 |
Средняя кнопка мыши | 1 | 4 |
Правая кнопка мыши, Кнопка пера | 2 | 2 |
Кнопка мыши X1 (назад) | 3 | 8 |
Кнопка мыши X2 (вперёд) | 4 | 16 |
Кнопка пера «ластик» | 5 | 32 |
Примечание: Свойство button указывает на изменение состояния кнопки. Однако, как и в случае с касанием, когда одно событие влечёт за собой ещё несколько событий, все они имеют одинаковое значение.
Pointer capture
Pointer capture allows events for a particular pointer event (en-US) to be re-targeted to a particular element instead of the normal hit test at a pointer’s location. This can be used to ensure that an element continues to receive pointer events even if the pointer device’s contact moves off the element (for example by scrolling).
The following example shows pointer capture being set on an element.
The following example shows a pointer capture being released (when a pointercancel event occurs. The browser does this automatically when a pointerup or pointercancel event occurs.
touch-action CSS property
The touch-action CSS property is used to specify whether or not the browser should apply its default (native) touch behavior (such as zooming or panning) to a region. This property may be applied to all elements except: non-replaced inline elements, table rows, row groups, table columns, and column groups.
In the following example, the browser’s default touch behavior is disabled for the div element.
In the following example, default touch behavior is disabled for some button elements.
In the following example, when the target element is touched, it will only pan in the horizontal direction.
Compatibility with mouse events
Although the pointer event interfaces enable applications to create enhanced user experiences on pointer enabled devices, the reality is the vast majority of today’s web content is designed to only work with mouse input. Consequently, even if a browser supports pointer events, the browser must still process mouse events so content that assumes mouse-only input will work as is without direct modification. Ideally, a pointer enabled application does not need to explicitly handle mouse input. However, because the browser must process mouse events, there may be some compatibility issues that need to be handled. This section contains information about pointer event and mouse event interaction and the ramifications for application developers.
The browser may map generic pointer input to mouse events for compatibility with mouse-based content. This mapping of events is called compatibility mouse events. Authors can prevent the production of certain compatibility mouse events by canceling the pointerdown event but note that:
Best practices
Here are some best practices to consider when using pointer events:
Specifications
Browser compatibility
BCD tables only load in the browser
Some new values have been defined for the css touch-action property as part of the Pointer Events – Level 3 specification but currently those new values have limited implementation support.
Практическое применение CSS свойства pointer-events
Что такое pointer-events
CSS свойство pointer-events было опубликовано в CSS4-UI в качестве дополнения к CSS3 свойствам.
W3C.org заявляет в спецификации:
The pointer-events property allows authors to control whether or when an element may be the target of user pointing device (pointer, e.g. mouse) events. This property is used to specify under which circumstance (if any) a pointer event should go “through” an element and target whatever is “underneath” that element instead. This also applies to other “hit testing” behaviors such as dynamic pseudo-classes (:hover, :active, :focus), hyperlinks, and Document.elementFromPoint()
Таким образомpointer-events – это свойство, позволяющее контролировать когда, как и может ли вообще указатель устройства (чаще всего мышь) взаимодействовать с элементом.
pointer-events: none предотвращает события указателя (как правило, мыши) для элемента: hover, active, click и т.п., в том числе и JavaScript событие click.
pointer-events: auto восстанавливает стандартное взаимодействие указателя с элементом.
Есть и другие значения свойства pointer-events, но они используются только при работе с SVG и я их не буду здесь рассматривать.
Небольшая особенность pointer-events, которую обязательно нужно учитывать
Предположим, вы установили для элемента JavaScript отслеживание события click. Затем выставили для него свойство pointer-events: none, а после этого опять поменяли этому элементу значение свойства pointer-events на auto. Тогда JavaScript, вызываемый при событии onclick, будет вызван опять при изменении значения свойства pointer-events на auto.
Кроссбраузерность pointer-events
Pointer-events, на удивление, поддерживается многими версиями браузеров. Но всё же подобные свойства нужно использовать аккуратно, чтобы не лишать пользователей возможности пользоваться основными функциями web приложения в старых версиях браузеров.
Так как же использовать pointer-events без вреда для кроссбраузерности? Можно воспользоваться Modernizr библиотекой для определения поддержки браузера этого свойства. А можно принять во внимание, что по сути подобная проблема возникнет в старой версии IE (так как другие браузеры обычно автоматически обновляются) и воспользоваться условными комментариями, если это возможно (пример 3).
Применение CSS свойства pointer-events на практике
Применений pointer-events в верстке можно найти в принципе столько, насколько у верстальщика хватит фантазии и потребностей. Есть парочка применений, которые и мне кажутся полезными. Напишу о них подробнее.
1. Предотвращение взаимодействия с изображениями
Если, к примеру, вы не хотите, чтобы у пользователя была возможность кликнуть правой кнопкой мыши по размещенному на сайте фото, то вы можете воспользоваться свойством pointer-event. Спасет ли это от незаконного копирования? Вряд ли…но жизнь воришке слегка подпортит.
See the Pen zKDev by Anastasiia Bakai (@positivecrash) on CodePen.
Правой картинке задано как раз свойство pointer-events. Попробуйте на практике покликать.
2. Ускорения скролла
Давненько уже было описано, что скролл – тяжелая процедура, при которой перерисовывается контент. Там же написано, что события для элемента такие, как hover, click и т.п. так же требуют перерисовки элементов, соответственно замедляют работу браузера. На хабре был предложен метод, который позволяет уменьшить подобную нагрузку на браузер как раз с помощью свойства pointer-event! Описывать тут метод не буду, в статье все хорошо описано. Способ, надо сказать, заманчивый. И возможно даже не будет никаких казусов в связи с особенностью обработки JavaScript, описанной мною выше.
3. Дизайн-элементы поверх интерактивных карт
Нарисовала я как-то дизайн, в котором ключевым элементом была карта. Сделала скриншот Google карты и наложила на нее пару теней для украшения:
Она понравилась моему начальнику и всё бы ничего..но вот в Illustrator я наложила на карту тени, а в вёрстке как быть? Тут на помощь как раз придёт CSS свойство pointer-events, который позволит наложить декоративные элементы поверх карты, при этом не “закрывая” области интерактивной карты от взаимодействия с пользователем. Как вы уже догадались, я просто добавлю строчку
События указателя
События указателя (Pointer events) – это современный способ обработки ввода с помощью различных указывающих устройств, таких как мышь, перо/стилус, сенсорный экран и так далее.
Краткая история
Сделаем небольшой обзор, чтобы вы поняли общую картину и место событий указателя среди других типов событий.
Давным-давно, в прошлом, существовали только события мыши
Но сенсорные устройства во многих аспектах мощнее, чем мышь. Например, они позволяют касаться экрана сразу в нескольких местах («мульти-тач»). Однако, события мыши не имеют необходимых свойств для обработки таких прикосновений.
Но и этих событий оказалось недостаточно, так как существует много других устройств, таких как перо, у которых есть свои особенности. Кроме того, универсальный код, который отслеживал бы и события касаний и события мыши, неудобно писать.
Для решения этих задач был внедрён стандарт Pointer Events («События Указателя»). Он предоставляет единый набор событий для всех типов указывающих устройств.
К настоящему времени спецификация Pointer Events Level 2 поддерживается всеми основными браузерами, а Pointer Events Level 3 находится в разработке и почти полностью совместима с Pointer Events Level 2.
Если вы не разрабатываете под старые браузеры, такие как Internet Explorer 10, Safari 12, или более ранние версии, больше нет необходимости использовать события мыши или касаний – можно переходить сразу на события указателя.
При этом ваш код будет корректно работать и с сенсорными устройствами и с мышью. Впрочем, у событий указателя есть важные особенности, которые нужно знать, чтобы их правильно использовать, без лишних сюрпризов. Мы отметим их в этой статье.
Типы событий указателя
Схема именований событий указателя похожа на события мыши:
Событие указателя | Аналогичное событие мыши |
---|---|
pointerdown | mousedown |
pointerup | mouseup |
pointermove | mousemove |
pointerover | mouseover |
pointerout | mouseout |
pointerenter | mouseenter |
pointerleave | mouseleave |
pointercancel | — |
gotpointercapture | — |
lostpointercapture | — |
Мы можем заменить события mouse. на аналогичные pointer. в коде и быть уверенными, что с мышью по-прежнему всё будет работать нормально.
Свойства событий указателя
pointerId – уникальный идентификатор указателя, вызвавшего событие.
Идентификатор генерируется браузером. Это свойство позволяет обрабатывать несколько указателей, например сенсорный экран со стилусом и мульти-тач (увидим примеры ниже).
pointerType – тип указывающего устройства. Должен быть строкой с одним из значений: «mouse», «pen» или «touch».
Мы можем использовать это свойство, чтобы определять разное поведение для разных типов указателей.
isPrimary – равно true для основного указателя (первый палец в мульти-тач).
Некоторые устройства измеряют область контакта и степень надавливания, например пальца на сенсорном экране, для этого есть дополнительные свойства:
Эти свойства большинством устройств не поддерживаются, поэтому редко используются. При необходимости, подробности о них можно найти в спецификации.
Мульти-тач
Одной из функций, которую абсолютно не поддерживают события мыши, является мульти-тач: возможность касаться сразу нескольких мест на телефоне или планшете или выполнять специальные жесты.
Вот что происходит, когда пользователь касается сенсорного экрана в одном месте, а затем в другом:
Вот небольшое демо, выводящее события pointerdown и pointerup :
Событие: pointercancel
Событие pointercancel происходит, когда текущее действие с указателем по какой-то причине прерывается, и события указателя больше не генерируются.
К таким причинам можно отнести:
Мы продемонстрируем pointercancel на практическом примере, чтобы увидеть, как это влияет на нас.
Допустим, мы реализуем перетаскивание («drag-and-drop») для нашего мяча, как в начале статьи Drag’n’Drop с событиями мыши.
Вот последовательность действий пользователя и соответствующие события:
Мы бы хотели реализовать перетаскивание самостоятельно, поэтому давайте скажем браузеру не перехватывать его.
Нужно сделать две вещи:
В данном демо произведены нужные действия:
Как вы можете видеть, событие pointercancel больше не срабатывает.
Теперь мы можем добавить код для перемещения мяча и наш drag’n’drop будет работать и для мыши и для устройств с сенсорным экраном.
Захват указателя
Захват указателя – особая возможность событий указателя.
Общая идея очень проста, но поначалу может показаться странной, так как для других событий ничего подобного просто нет.
Эта привязка отменяется:
Захват указателя используется для упрощения операций с переносом (drag’n’drop) элементов.
В качестве примера давайте вспомним реализацию слайдера из статьи Drag’n’Drop с событиями мыши.
Мы делаем элемент для слайдера – полоску с «ползунком» ( thumb ) внутри.
Затем он работает так:
Такое решение выглядит слегка «грязным». Одна из проблем – это то, что движения указателя по документу могут вызвать сторонние эффекты, заставить сработать другие обработчики, не имеющие отношения к слайдеру.
Захват указателя позволяет привязать pointermove к thumb и избежать любых подобных проблем:
pointer-events
Описание
CSS-свойство pointer-events позволяет контролировать события, при которых элемент может стать объектом события мыши. Если это свойство не задано, то к содержимому SVG будут применяться характеристики значения visiblePainted.
Вдобавок к указанию того, что элемент не является объектом события мыши, значение none сообщает событию мыши проходить «через» элемент и обращаться к элементу, находящемуся «под» ним.
Начальное значение | auto |
---|---|
Применяется к | все элементы |
Наследуется | да |
Обработка значения | как указано |
Animation type | discrete |
Синтаксис
Значения
Формальный синтаксис
Примеры
Пример 1
Пример 2
Сделать ссылку на ресурс http://example.com не реагирующей на нажатие(click), наведение(:hover) и т.д.
Примечание
Обратите внимание, что предотвращение того, чтобы элемент был объектом событий мыши, с помощью pointer-events не обязательно означает, что обработчики событий мыши на этом элементе не могут или не будут запускаться. Если у одного из дочерних элементов есть явные pointer-events, позволяющие этому ребёнку быть объектом событий мыши, тогда любые события, нацеленные на этого дочернего элемента, будут проходить через родителя, когда событие перемещается вдоль родительской цепочки и запускает обработчики событий на родительском объекте. Конечно, любая активность мыши в точке на экране, которая покрывается родителем, но не дочерним, не будет поймана ни ребёнком, ни родителем (он пройдёт через «родительский» на «цели» под ним).
Мы хотели бы предоставить более тонкий контроль (а не только auto и none ) в HTML, когда части элемента смогут «поймать» события мыши. Если у вас есть какие-то конкретные вещи, чтобы помочь нам в решении как следует расширить pointer-events для HTML, и которые вы хотели бы сделать с этим свойством, добавьте их в раздел «Использовать случаи» на этой странице вики (не беспокойтесь, мы всё сохраним аккуратно).
Характеристики
Это расширение для элементов HTML, хоть и присутствует в ранних версиях CSS Basic User Module Interface Level 3, было перенесено на level 4.
Pointer-events
Представим ситуацию, когда у нас один html-элемент расположен поверх другого. Но нам нужно, чтобы нижний элемент был кликабельным или реагировал на hover.
pointer-events : none — элемент перестанет реагировать на hover, click и другие события мыши. Он станет «прозрачным» для взаимодействия, а hover и click будут передаваться элементу, лежащему под ним.
pointer-events : auto — (значение по-умолчанию) включает стандартное поведение элемента.
Изначально свойство «pointer-events» было введено для SVG и должно было стать частью CSS3, но было перенесено в спецификацию CSS4. Кроме «none» и «auto» есть еще несколько значений, но они применимы только к SVG, и мы не будем их рассматривать.
Несмотря на то, что свойство относится к CSS4, pointer-events поддерживается уже большим количеством браузеров и довольно давно. Не работает в IE ниже 11 версии и в Opera Presto. А значит, его можно осторожно использовать для улучшения юзабилити в рамках прогрессивного улучшения.
Проверить, поддерживается ли это свойство браузером, можно с помощью специального теста для Modernizer.
Пример 1
Рассмотрим на практике.
В первом примере для белого градиента, накрывающего текст, pointer-events установлен в none. Текст легко выделяется мышью сквозь градиент. Даже курсор меняет свою форму со стрелки на выделение текста.
Во втором примере pointer-events не задан, маска градиента не даёт выделить текст, курсор имеет форму стрелки, как для нетекстовых элементов.
Пример 2
Задача: сделать так, чтобы ссылка в меню становилась некликабельной, если она ведет на эту же страницу.
Обычно в CMS уже есть какой-либо класс для индикации текущей страницы в меню. Допишем ему pointer-events: