From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../events/criando_e_disparando_eventos/index.html | 145 +++++++++ .../web/guide/events/event_handlers/index.html | 164 ++++++++++ files/pt-br/web/guide/events/index.html | 36 +++ .../web/guide/events/mutation_events/index.html | 62 ++++ .../overview_of_events_and_handlers/index.html | 132 ++++++++ .../pt-br/web/guide/events/touch_events/index.html | 353 +++++++++++++++++++++ 6 files changed, 892 insertions(+) create mode 100644 files/pt-br/web/guide/events/criando_e_disparando_eventos/index.html create mode 100644 files/pt-br/web/guide/events/event_handlers/index.html create mode 100644 files/pt-br/web/guide/events/index.html create mode 100644 files/pt-br/web/guide/events/mutation_events/index.html create mode 100644 files/pt-br/web/guide/events/overview_of_events_and_handlers/index.html create mode 100644 files/pt-br/web/guide/events/touch_events/index.html (limited to 'files/pt-br/web/guide/events') diff --git a/files/pt-br/web/guide/events/criando_e_disparando_eventos/index.html b/files/pt-br/web/guide/events/criando_e_disparando_eventos/index.html new file mode 100644 index 0000000000..632b54df75 --- /dev/null +++ b/files/pt-br/web/guide/events/criando_e_disparando_eventos/index.html @@ -0,0 +1,145 @@ +--- +title: Criando e disparando eventos +slug: Web/Guide/Events/criando_e_disparando_eventos +tags: + - Avançado + - DOM + - Guía + - JavaScript + - eventos +translation_of: Web/Guide/Events/Creating_and_triggering_events +--- +

Este artigo demonstra como criar e disparar eventos DOM. Tais eventos são comumente chamados eventos sintéticos, oposto aos eventos disparados pelo próprio navegador.

+ +

Criando eventos customizados

+ +

Eventos podem ser criados com o construtor Event da seguinte forma:

+ +
var event = new Event('build');
+
+// Ouve pelo evento.
+elem.addEventListener('build', function (e) { ... }, false);
+
+// Dispara o evento.
+elem.dispatchEvent(event);
+ +

Este construtor é suportado na maioria dos navegadores modernos (com o Internet Explorer sendo exceção). Para uma abordagem mais verbosa (a qual é suportada pelo Internet Explorer), veja a forma antiga abaixo.

+ +

Adicionando dados customizados – CustomEvent()

+ +

Para adicionar mais dados ao objeto do evento, usa-se a interface CustomEvent, a qual possui a propriedade detail que pode ser utilizada para fornecer dados customizados.

+ +

Por exemplo, o evento pode ser criado da seguinte forma:

+ +
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
+ +

Isso permitirá que você acesse dados customizados no listener do evento:

+ +
function eventHandler(e) {
+  console.log('The time is: ' + e.detail);
+}
+
+ +

A forma antiga

+ +

A forma antiga de criar eventos possui uma abordagem mais verbosa, tendo APIs inspiradas em Java. Abaixo temos um exemplo:

+ +
// Cria o evento.
+var event = document.createEvent('Event');
+
+// Define que o nome do evento é 'build'.
+event.initEvent('build', true, true);
+
+// Ouve pelo evento.
+elem.addEventListener('build', function (e) {
+  // e.target é igual a elem, neste caso
+}, false);
+
+// O alvo do evento pode ser qualquer instância de Element ou EventTarget.
+elem.dispatchEvent(event);
+
+
+ +

Disparando eventos nativos

+ +

Este exemplo mostra a simulação de um clique (isto é, gera um um clique de forma programatica) sobre um checkbox usando métodos DOM. Veja o exemplo em ação.

+ +
function simulateClick() {
+  var event = new MouseEvent('click', {
+    'view': window,
+    'bubbles': true,
+    'cancelable': true
+  });
+
+  var cb = document.getElementById('checkbox');
+  var cancelled = !cb.dispatchEvent(event);
+
+  if (cancelled) {
+    // Um listener invocou o método preventDefault.
+    alert("Cancelado");
+  } else {
+    // Nenhum listener invocou o método preventDefault.
+    alert("Não cancelado");
+  }
+}
+ +

Compatibilidade entre navegadores

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)EdgeInternet ExplorerOperaSafari (WebKit)
construtor Event()1511{{CompatVersionUnknown}}1111.606
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte básico{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}6
+
+ +

Veja também

+ + diff --git a/files/pt-br/web/guide/events/event_handlers/index.html b/files/pt-br/web/guide/events/event_handlers/index.html new file mode 100644 index 0000000000..f558992d27 --- /dev/null +++ b/files/pt-br/web/guide/events/event_handlers/index.html @@ -0,0 +1,164 @@ +--- +title: DOM onevent handlers +slug: Web/Guide/Events/Event_handlers +translation_of: Web/Guide/Events/Event_handlers +--- +

A plataforma web oferece várias maneiras de trabalhar com o DOM events. Duas abordagens comuns são: {{domxref("EventTarget.addEventListener", "addEventListener()")}} e o específico onevent que dispara um evento. Este artigo se concentra em como o último funciona.

+ +

Registering onevent handlers

+ +

The onevent handlers are properties on certain DOM elements to manage how that element reacts to events. Elements can be interactive (links, buttons, images, forms, and so forth) or non-interactive (such as the base <body> element). Events are actions like:

+ + + +

The on-event handler is usually named with the event it reacts to, like onclick, onkeypress, onfocus, etc.

+ +

You can specify an on<…> event handler for a particular event (such as {{event("click")}}) for a given object in different ways:

+ + + +

An onevent event handler property serves as a placeholder of sorts, to which a single event handler can be assigned. In order to allow multiple handlers to be installed for the same event on a given object, you can call its {{domxref("EventTarget.addEventListener", "addEventListener()")}} method, which manages a list of handlers for the given event on the object. A handler can then be removed from the object by calling its {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} function.

+ +

When an event occurs that applies to an element, each of its event handlers is called to allow them to handle the event, one after another. You don't need to call them yourself, although you can do so in many cases to easily simulate an event taking place. For example, given a button object myButton, you can do myButton.onclick(myEventObject) to call the event handler directly. If the event handler doesn't access any data form the event object, you can leave out the event when calling onclick().

+ +

This continues until every handler has been called, unless one of the event handlers explicitly halts the processing of the event by calling {{domxref("Event.stopPropagation", "stopPropagation()")}} on the event object itself.

+ +

Non-element objects

+ +

Event handlers can also be set with properties on non-element objects that generate events, like {{ domxref("window") }}, {{ domxref("document") }}, {{ domxref("XMLHttpRequest") }}, and others. For example, for the progress event on instances of XMLHttpRequest:

+ +
const xhr = new XMLHttpRequest();
+xhr.onprogress = function() { … };
+ +

HTML onevent attributes

+ +

HTML elements have attributes named onevent which can be used to register a handler for an event directly within the HTML code. When the element is built from the HTML, the value of its onevent attributes are copied to the DOM object that represents the element, so that accessing the attributes' values using JavaScript will get the value set in the HTML.

+ +

Further changes to the HTML attribute value can be done via the setAttribute method; Making changes to the JavaScript property will have no effect.

+ +

HTML

+ +

Given this HTML document:

+ +
<p>Demonstrating quirks of <code>on<em>event</em></code> HTML attributes on
+   <a onclick="log('Click!')">these three words</a>.
+</p>
+
+<div></div>
+ +

JavaScript

+ +

Then this JavaScript demonstrates that the value of the HTML attribute is unaffected by changes to the JavaScript object's property.

+ +
let logElement = document.querySelector('div');
+let el = document.querySelector("a");
+
+function log(msg) { logElement.innerHTML += `${msg}<br>` };
+function anchorOnClick(event) { log("Changed onclick handler") };
+
+// Original Handler
+log(`Element's onclick as a JavaScript property: <code> ${el.onclick.toString()} </code>`);
+
+//Changing handler using .onclick
+log('<br>Changing onclick handler using <strong> onclick property </strong> ');
+
+el.onclick = anchorOnClick;
+
+log(`Changed the property to: <code> ${el.onclick.toString()} </code>`);
+log(`But the HTML attribute is unchanged: <code> ${el.getAttribute("onclick")} </code><br>`);
+
+//Changing handler using .setAttribute
+log('<hr/><br> Changing onclick handler using <strong> setAttribute method </strong> ');
+el.setAttribute("onclick", 'anchorOnClick(event)');
+
+log(`Changed the property to: <code> ${el.onclick.toString()} </code>`);
+log(`Now even the HTML attribute has changed: <code> ${el.getAttribute("onclick")} </code><br>`);
+ +

Result

+ +

{{ EmbedLiveSample('HTML_onevent_attributes', '', '', '', 'Web/Guide/Events/Event_handlers') }}

+ +

For historical reasons, some attributes/properties on the {{HTMLElement("body")}} and {{HTMLElement("frameset")}} elements instead set event handlers on their parent {{domxref("Window")}} object. (The HTML specification names these: onblur, onerror, onfocus, onload, and onscroll.)

+ +

Event handler's parameters, this binding, and the return value

+ +

When the event handler is specified as an HTML attribute, the specified code is wrapped into a function with the following parameters:

+ + + +

When the event handler is invoked, the this keyword inside the handler is set to the DOM element on which the handler is registered. For more details, see the this keyword documentation.

+ +

The return value from the handler determines if the event is canceled. The specific handling of the return value depends on the kind of event; for details, see "The event handler processing algorithm" in the HTML specification.

+ +

When the event handler is invoked

+ +
+

TBD (non-capturing listener)

+
+ +

Terminology

+ +

The term event handler may refer to:

+ + + +

When discussing the various methods of listening to events:

+ + + +

Specifications

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#event-handler-attributes', 'event handlers')}}{{Spec2('HTML WHATWG')}}
{{SpecName('HTML5 W3C', 'webappapis.html#event-handler-attributes', 'event handlers')}}{{Spec2('HTML5 W3C')}}
+ +

Browser compatibility

+ +

Detecting the presence of event handler properties

+ +

You can detect the presence of an event handler property with the JavaScript in operator. For example:

+ +
if ("onsomenewfeature" in window) {
+  /* do something amazing */
+}
+
+ +

Event handlers and prototypes

+ +

You can't set or access the values of any IDL-defined attributes on DOM prototype objects. That means you can't, for example, change Window.prototype.onload. In the past, event handlers (onload, etc.) weren't implemented as IDL attributes in Gecko, so you were able to do this for those. Now you can't. This improves compatibility.

diff --git a/files/pt-br/web/guide/events/index.html b/files/pt-br/web/guide/events/index.html new file mode 100644 index 0000000000..65b5775a16 --- /dev/null +++ b/files/pt-br/web/guide/events/index.html @@ -0,0 +1,36 @@ +--- +title: Event developer guide +slug: Web/Guide/Events +tags: + - DOM + - Event + - Guide + - NeedsTranslation + - TopicStub + - events +translation_of: Web/Guide/Events +--- +

{{draft()}}

+

Events refers both to a design pattern used for the asynchronous handling of various incidents which occur in the lifetime of a web page and to the naming, characterization, and use of a large number of incidents of different types.

+

The overview page provides an introduction to the design pattern and a summary of the types of incidents which are defined and reacted to by modern web browsers.

+

The custom events page describes how the event code design pattern can be used in custom code to define new event types emitted by user objects, register listener functions to handle those events, and trigger the events in user code.

+

The remaining pages describe how to use events of different kinds defined by web browsers. Unfortunately, these events have been defined piece by piece as web browsers have evolved so that there is no satisfying systematic characterization of the events built-in or defined by modern web browsers.

+

The device on which the web browser is running can trigger events, for example due to a change in its position and orientation in the real world, as discussed partially by the page on orientation coordinate systems and the page on the use of 3D transforms. That is different, but similar, to the change in device vertical orientation. 

+

The window in which the browser is displayed which might trigger events, for example, change size if the user maximizes the window or otherwise changes it.

+

The process loading of a web page might trigger events in response to the completion of different steps in the downloading, parsing, and rendering of the web page for display to the user.

+

The user interaction with the web page contents might trigger events. The events triggered by user interaction evolved during the early years of browser design and include a complicated system defining the sequence in which events will be called and the manner in which that sequence can be controlled. The different types of user interaction driven events include:

+ +

The modification of the web page in structure or content might trigger some events, as is explained in the mutation events page, but the use of these events has been deprecated in favour of the lighter Mutation Observer approach.

+

The media streams embedded in the HTML documents might trigger some events, as explained in the media events page.

+

The network requests made by a web page might trigger some events.

+

There are many other sources of events defined by web browsers for which pages are not yet available in this guide.

+
+

Note: This Event Developer Guide needs substantial work. The structure needs to be reorganized and the pages rewritten. Our hope is that everything you need to know about events will go under here.

+
+

Docs

+

{{LandingPageListSubpages}}

diff --git a/files/pt-br/web/guide/events/mutation_events/index.html b/files/pt-br/web/guide/events/mutation_events/index.html new file mode 100644 index 0000000000..582670fb98 --- /dev/null +++ b/files/pt-br/web/guide/events/mutation_events/index.html @@ -0,0 +1,62 @@ +--- +title: Mutation events +slug: Web/Guide/Events/Mutation_events +translation_of: Web/Guide/Events/Mutation_events +--- +

{{deprecated_header()}}

+ +

Mutation events fornecem um mecanismo, para uma página web ou uma extensão, de notificação sobre as alterações feitas no DOM. Utilize ao invés, se possível, Mutation Observers.

+ +

Prefácio

+ +

Os eventos de mutação foram marcados como em desuso na DOM Events specification pelo fato do projeto da API ser falho (veja detalhes no "DOM Mutation Events Replacement: The Story So Far / Existing Points of Consensus" publicado em public-webapps).

+ +

Mutation Observers são a proposta de substituição para eventos de mutação no DOM4. Eles devem ser incluídos no Firefox 14 e Chrome 18.

+ +

As razões práticas para evitar os eventos de mutação são problemas de desempenho e suporte cross-browser.

+ +

Performance

+ +

Adicionando listeners de mutação do DOM a um documento degrada o desempenho profundamente de outras modificações DOM para esse documento (tornando-os 1.5 - 7 vezes mais lento!). Além disso, remover os listeners não reverte o dano.

+ +

O efeito de desempenho é limitado aos documentos que têm os listeners de evento de mutação.

+ +

Suporte cross-browser

+ +

Esses eventos não são implementados de forma consistente entre os diferentes navegadores, por exemplo:

+ + + +

Dottoro suporte a eventos de mutação nos navegadores.

+ +

Lista de mutation events

+ +

Listado a seguir todos os eventos de mutação, como definido no DOM Level 3 Events specification:

+ + + +

Uso

+ +

Você pode registrar um listener para eventos de mutação usando element.addEventListener, como mostrado a seguir:

+ +
element.addEventListener("DOMNodeInserted", function (event) {
+  // ...
+}, false);
+
+ +

O objeto event é transmitido para o listener em um {{ domxref("MutationEvent") }} (veja sua definição na especificação) para a maioria dos eventos, e {{ domxref("MutationNameEvent") }} para DOMAttributeNameChanged e DOMElementNameChanged.

diff --git a/files/pt-br/web/guide/events/overview_of_events_and_handlers/index.html b/files/pt-br/web/guide/events/overview_of_events_and_handlers/index.html new file mode 100644 index 0000000000..2593d5641e --- /dev/null +++ b/files/pt-br/web/guide/events/overview_of_events_and_handlers/index.html @@ -0,0 +1,132 @@ +--- +title: Uma visão geral sobre Events e Handlers +slug: Web/Guide/Events/Overview_of_Events_and_Handlers +translation_of: Web/Guide/Events/Overview_of_Events_and_Handlers +--- +
+

Este artigo apresenta uma visão geral sobre o design pattern usado para reagir a alterações que ocorrem quando o navegador acessa uma página, e dá um resumo sobre como os navegadores modernos reagem a eles.

+
+ +

Eventos e a manipulação de eventos fornecem uma técnica essencial em JavaScript para reagir a algum incidente quando o navegador acessa uma página, incluindo eventos de preparação para exibir a página, ou interação com algum conteúdo da página que estejam relacionados com o dispositivo onde o navagador está rodando, e muitas outras, como reprodução de áudio ou vídeo.

+ +

A manipulação de eventos tornou-se imprescindível com a evolução e mudança na arquitetura de renderização dos navegadores em relação a forma de busca e carregamento de informações na página. No início, os navegadores esperavam e recebiam os dados e recursos associados a página para analisar, processar e apresentar a página ao usuário. A página permanecia inalterada até uma requisição para um novo link. Atualmente, com a mudança para páginas dinâmicas, os navegadores estão sempre em um loop contínuo, processando, desenhando, apresentando conteúdo e esperando de algum novo evento. Os gatilhos (triggers) de evento podem ser a conclusão do carregamento de um arquivo na rede, por exemplo, uma imagem que agora pode ser mostrada na tela, a conclusão da análise de um recurso pelo navegador, o processamento do conteúdo HTML de uma página, a interação de um usuário com o conteúdo da página, com o clique em um botão. Douglas Crockford explica essa mudança de maneira eficaz em sua palestra, An Inconvenient API: The Theory of the DOM.

+ +

With the change to dynamic page rendering, browsers loop continuously between processing, drawing, presenting content, and waiting for some new event trigger. Event triggers include the completion of the loading of a resource on the network e.g., downloads an image that can now be drawn on the screen, the completion of parsing a resource by the browser e.g., processes the HTML content of a page, the interaction of a user with the contents of the page e.g., clicks a button. Douglas Crockford explains this change effectively in several lectures, notably his talk, An Inconvenient API: The Theory of the DOM, which shows the change in flow from the original browser flow

+ +
A comparison of the sequential and event-driven browser load sequences.
+ +

to the event driven browser. The latter approach changes the last steps from a single flow into a perpetual loop, where waiting for and handling the incidence of new events follows painting. The innovation of the dynamic approach allows for a page to be partially rendered even when the browser has not finished retrieving all resources; this approach also allows for event driven actions, which JavaScript leverages. (The talk is available from several sources, including this one.) Currently, all execution environments for JavaScript code use events and event handling.

+ +

The event design pattern

+ +

The event system, at its core, is simply a programming design pattern. The pattern starts with an agreement over a kind of event and:

+ + + +

The pattern is implemented by

+ + + +

The function is said to be a 'listener' or a 'handler' with both names used interchangeably. This pattern can easily be followed using completely custom code, as explained in the article on custom events. The pattern is also used by modern web browsers which define many events emitted in response to user input or browser activity.

+ +

Modern web browsers follow the event pattern using a standardized approach. Browsers use as the data structure for the properties of the event, an object derived from the EventPrototype object. Browsers use as the registration method for the function which will handle those data structures a method called addEventListener which expects as arguments a string event type name and the handler function. Finally, browsers define a large number of objects as event emitters and define a wide variety of event types generated by the objects.

+ +

Button Event Handler Demo

+ +

For example, browser button elements are intended to emit events named 'click' in response to a mouse click or, when displayed in touch sensitive surfaces, to a finger tap. We could define in the HTML page a button as:

+ +
<button id="buttonOne">Click here to emit a 'click' event</button>
+ +

and, in our JavaScript code, we could first define a function to listen to that 'click' event:

+ +
var example_click_handler = function (ev){
+    var objKind = (ev instanceof Event) ? "EventPrototype" : "ObjectPrototype";
+    alert("We got a click event at " + ev.timeStamp + " with an argument object derived from: " + objKind );
+};
+ +

and second register our function with the the Button object, either on the scripting side using the DOM (Document Object Model) representation of the HTML page:

+ +
var buttonDOMElement = document.querySelector('#buttonOne');
+buttonDOMElement.addEventListener('click', example_click_handler);
+ +

or within the HTML page by adding the function as the value of the 'onclick' attribute, although this second approach is usually only used in very simple web pages.

+ +

{{ EmbedLiveSample('Button_Event_Handler') }}

+ +

This code relies on the agreement that there is a kind of event called 'click' which will call any listener (or 'handler') function with an Event object argument (actually, in this case a derivative MouseEvent object) and which will be fired by HTML button elements after user interaction. The code has no visible effect until a user interacts with the button either by placing the mouse pointer over the HTML button and clicking on the left mouse button or by placing a finger or stylus of some kind on the screen above the HTML button; when that happens, the buttonDOMElement JavaScript object would call the example_click_handler function with an Event object as an argument. The function, in turn, would perform whatever action was chosen by the programmer, in this case to open an HTML alert dialog. Note that the handler has access to the ev object since it is passed as an argument; the object has information about the event, notably the time at which the event occurred.

+ +

As a second example, much modern JavaScript integrated into web pages is wrapped into an event function call to ensure that the code is only executed when the HTML has been processed and is available for alteration or decoration. For example, code might be attached as:

+ +
var funcInit = function(){
+    // user code goes here and can safely address all the HTML elements from the page
+    // since the document has successfully been 'loaded'
+}
+document.addEventListener('DOMContentLoaded', funcInit);
+
+ +

so that this code will only be executed after the document object emits the 'DOMContentLoaded' event because the HTML has been parsed and Javasript objects created representing each of the nodes of the HTML document. Note that in this example, the code does not even name the event argument to the function because the code never needs to use the data structure describing the event; rather, the code merely needs to wait to run until after then event has happened.

+ +

The pattern is therefore easy to learn and implement. The difficulty with events comes from learning the wide variety of events which are generated in modern web browsers. There is also some subtlety in learning how to write the handler functions since such code works asynchronously and potentially will run repeatedly but in slightly different situations.

+ +

Notable events

+ +

Web browsers define a large number of events so it is not practical to list them all. The Event Reference attempts to maintain a list of the standard Events used in modern web browsers.

+ +

In general, we can distinguish events of different kinds based on the object emitting the event including:

+ + + +

although this list is currently incomplete.

+ +

Some notable events are:

+ +
+

Note: This list of events will need work to make relevant; that work is awaiting some global reorganization work on the documents. This will also need finding a good explanation of the events involved during page loading, such as discussed partially in this web page or in this Stack Overflow question.

+
+ + + + + +

The Event object hierarchy

+ +

The web browser defines many events of different kinds. Each definition includes, as the data structure passed to the handler function, an object which inherits from the EventPrototype object.

+ +

A partial diagram of the class hierarchy of event objects is:

+ +
+

Note: This diagram is incomplete.

+
+ +

+ +

The Web API Documentation contains a page defining the Event object which also includes the known DOM event subclasses of the Event object.

+ +

Documents

+ +

Three sources on the MDN (Mozilla Developer Network) web site are particularly useful for programmers wanting to work with events:

+ + diff --git a/files/pt-br/web/guide/events/touch_events/index.html b/files/pt-br/web/guide/events/touch_events/index.html new file mode 100644 index 0000000000..df21cdf335 --- /dev/null +++ b/files/pt-br/web/guide/events/touch_events/index.html @@ -0,0 +1,353 @@ +--- +title: Eventos do Toque +slug: Web/Guide/Events/Touch_events +tags: + - Avançado + - DOM + - Evento + - Guía + - Mobile + - Visualização +translation_of: Web/API/Touch_events +--- +

Com a finalidade de fornecer suporte de qualidade para interfaces baseadas em toque (touch), os eventos de touch oferecem a capacidade de interpretar a atividade em telas sensíveis ao toque ou trackpads.

+ +

Definições

+ +
+
Surface
+
A superfície sensível ao toque. Pode ser uma tela ou trackpad.
+
+ +
+
Touch point
+
Um ponto de contato com a superfície. Pode ser um dedo (ou cotovelo, orelha, nariz, o que seja, mas provavelmente, um dedo) ou uma caneta.
+
+ +

Interfaces

+ +
+
{{ domxref("TouchEvent") }}
+
Representa um evento quando ocorre o estado de toque na superfície.
+
{{ domxref("Touch") }}
+
Representa um único ponto de contato entre o usuário e a superfície sensível a toque.
+
{{ domxref("TouchList") }}
+
Representa um grupo de toques, isto é usado quando usuário tem por exemplo, vários dedos ao mesmo tempo sobre a superfície.
+
{{ domxref("DocumentTouch") }}
+
Contém métodos de conveniência para criar {{ domxref("Touch") }} e objetos {{ domxref("TouchList") }} .
+
+ +

Exemplo

+ +

Este exemplo acompanha múltiplos pontos de contato de cada vez, permitindo o usuário desenhe em um {{ HTMLElement("canvas") }} com mais de um dedo por vez. Ele só funcionará em um browser que tenha suporte a eventos de toque.

+ +
Nota: O texto a seguir utiliza o termo "finger" quando descreve o contato com a superfície, mas poderia, é claro, ser também uma caneta ou outro método de contato.
+ +

Crie um canvas

+ +
<canvas id="canvas" width="600" height="600" style="border:solid black 1px;">
+  Seu browser não tem suporte ao elemento canvas.
+</canvas>
+<br>
+<button onclick="startup()">Initialize</button>
+<br>
+Log: <pre id="log" style="border: 1px solid #ccc;"></pre>
+
+ +

Configurado os eventos

+ +

Quando uma página é carregada, a função startup() mostrada abaixo deve ser chamada pelo nosso elemento {{ HTMLElement("body") }} através do atributo onload (Mas no exemplo usamos um botão para adicioná-lo, devido as limitações do MDN live example system).

+ +
function startup() {
+  var el = document.getElementsByTagName("canvas")[0];
+  el.addEventListener("touchstart", handleStart, false);
+  el.addEventListener("touchend", handleEnd, false);
+  el.addEventListener("touchcancel", handleCancel, false);
+  el.addEventListener("touchleave", handleEnd, false);
+  el.addEventListener("touchmove", handleMove, false);
+  log("initialized.");
+}
+
+ +

Define simplesmento todos os ouvintes dos eventos do nosso elemento {{ HTMLElement("canvas") }} para que possamos trabalhar com os eventos de toque quando eles ocorrerem.

+ +

Rastreando novos toques

+ +

Vamos acompanhar os toques em seu progresso.

+ +
var ongoingTouches = new Array; 
+ +

Quando ocorre um evento touchstart, indicando que um novo toque na superfície tenha ocorrido, a função abaixo handleStart() é chamada. 

+ +
function handleStart(evt) {
+  evt.preventDefault();
+  log("touchstart.");
+  var el = document.getElementsByTagName("canvas")[0];
+  var ctx = el.getContext("2d");
+  var touches = evt.changedTouches;
+
+  for (var i=0; i < touches.length; i++) {
+    log("touchstart:"+i+"...");
+    ongoingTouches.push(copyTouch(touches[i]));
+    var color = colorForTouch(touches[i]);
+    ctx.beginPath();
+    ctx.arc(touches[i].pageX, touches[i].pageY, 4, 0,2*Math.PI, false);  // a circle at the start
+    ctx.fillStyle = color;
+    ctx.fill();
+    log("touchstart:"+i+".");
+  }
+}
+
+ +

A chamada {{ domxref("event.preventDefault()") }} mantem o browser a processa o evento de toque ( isso também previne que um mouse event seja despachado). Então, temos o contexto e puxamos a lista de pontos de contato disparados noa propriedade do evento {{ domxref("TouchEvent.changedTouches") }}.

+ +

Depois disso, nós iteramos sobre todos os objetos {{ domxref("Touch") }} da lista e os adicionamos em um array de pontos de contatos ativos e definimos o ponto inicial para desenhar um pequeno circulo; estamos usando um raio de 4 pixels, então um círculo de 4 pixels irá aparecer em nosso canvas.

+ +

Desenhando movimento do toque

+ +

Cada vez que um ou mais dedos se movem, um evento de TouchMove é disparado, assim chamando nossa função handleMove(). A sua responsabilidade neste exemplo é atualizar as informações armazenadas e desenhar uma linha a partir da posição anterior para a atual de cada toque.

+ +
function handleMove(evt) {
+  evt.preventDefault();
+  var el = document.getElementsByTagName("canvas")[0];
+  var ctx = el.getContext("2d");
+  var touches = evt.changedTouches;
+
+  for (var i=0; i < touches.length; i++) {
+    var color = colorForTouch(touches[i]);
+    var idx = ongoingTouchIndexById(touches[i].identifier);
+
+    if(idx >= 0) {
+      log("continuing touch "+idx);
+      ctx.beginPath();
+      log("ctx.moveTo("+ongoingTouches[idx].pageX+", "+ongoingTouches[idx].pageY+");");
+      ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
+      log("ctx.lineTo("+touches[i].pageX+", "+touches[i].pageY+");");
+      ctx.lineTo(touches[i].pageX, touches[i].pageY);
+      ctx.lineWidth = 4;
+      ctx.strokeStyle = color;
+      ctx.stroke();
+
+      ongoingTouches.splice(idx, 1, copyTouch(touches[i]));  // swap in the new touch record
+      log(".");
+    } else {
+      log("can't figure out which touch to continue");
+    }
+  }
+}
+
+ +

Esta interação sobre os toques também muda, mas parece em cache as  informações em um array para cada toque anterior, a fim de determinar um pont de partida e o destino para o desenho do trajeto. Isto é feito para olhar cada touch da propriedade {{ domxref("Touch.identifier") }}. Esta propriedade é um número inteiro único para cada toque, e mantém-se consistente para cada evento durante o tempo de contato de cada dedo como a superfície.

+ +

Isto permite obter as coordenadas da posição anterior de cada contato e usar os métodos de contexto apropriado para desenhar uma linha que une as duas posições.

+ +

Depois de desenhar a linha, nós chamamos Array.splice() para substituir as informações previas sobre o ponto de toque com a informação atual no array ongoingTouches.

+ +

Gerenciando o final do evento de toque 

+ +

Quando o usuário retira o dedo da superfície , um evento touchend é disparado.  Da mesma forma, se o dedo deslisa para fora do canvas, nós teremos um evento touchleave disparado. Nós tratamos da mesma forma em ambos os casos:  chamamos  a função handleEnd(). A sua missão é desenhar uma linha para o final do ponto de toque e remover o ponto de toque da lista ongoing.

+ +
function handleEnd(evt) {
+  evt.preventDefault();
+  log("touchend/touchleave.");
+  var el = document.getElementsByTagName("canvas")[0];
+  var ctx = el.getContext("2d");
+  var touches = evt.changedTouches;
+
+  for (var i=0; i < touches.length; i++) {
+    var color = colorForTouch(touches[i]);
+    var idx = ongoingTouchIndexById(touches[i].identifier);
+
+    if(idx >= 0) {
+      ctx.lineWidth = 4;
+      ctx.fillStyle = color;
+      ctx.beginPath();
+      ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
+      ctx.lineTo(touches[i].pageX, touches[i].pageY);
+      ctx.fillRect(touches[i].pageX-4, touches[i].pageY-4, 8, 8);  // and a square at the end
+      ongoingTouches.splice(idx, 1);  // remove it; we're done
+    } else {
+      log("can't figure out which touch to end");
+    }
+  }
+}
+
+ +

Isto é muito semelhante a função anterior, as únicas diferenças reais são o desenho de um pequeno quadrado para marcar o fim e quando chamamos Array.splice(), nós simplesmente removemos a antiga entrada da lista de toque do ongoing, sem adição das informações atualizadas. O resultado é que paramos o tracking do ponto de contato.

+ +

Tratando toques cancelados

+ +

Se o dedo do usuário deslisa em uma UI de um navegador, ou o toque de outra forma precisa ser cancelado, o evento touchcancel é disparado e nos chamamaos a função handleCancel().

+ +
function handleCancel(evt) {
+  evt.preventDefault();
+  log("touchcancel.");
+  var touches = evt.changedTouches;
+
+  for (var i=0; i < touches.length; i++) {
+    ongoingTouches.splice(i, 1);  // remove it; we're done
+  }
+}
+
+ +

Uma vez que a idéia dé cancelar imediatamento o toque, nós simplesmente removemos da lista de ongoing sem desenhar uma linha final.

+ +

Funções de conveniência

+ +

Este exemplo usa duas funções de conveniência que deve ser olhado rapidamente para ajudar a fazer o resto do código mais claro

+ +

Selecionando a cor para cada toque

+ +

A fim de fazer cada toque desenhar com uma cor diferente, a função  colorForTouch()  é usada para escolher uma cor com base em um identificador único do toque, Este identificador é um número opaco, mas pelo menos podemos conta com ele diferindo entre os toques ativos no momento.

+ +
function colorForTouch(touch) {
+  var r = touch.identifier % 16;
+  var g = Math.floor(touch.identifier / 3) % 16;
+  var b = Math.floor(touch.identifier / 7) % 16;
+  r = r.toString(16); // make it a hex digit
+  g = g.toString(16); // make it a hex digit
+  b = b.toString(16); // make it a hex digit
+  var color = "#" + r + g + b;
+  log("color for touch with identifier " + touch.identifier + " = " + color);
+  return color;
+}
+
+ +

O resultado desta função é uma string que pode ser usada ao chamar as funções {{ HTMLElement("canvas") }} para setar a cor do desenho. Por exemplo, para um valor  {{ domxref("Touch.identifier") }} de 10, o resultado será a string "#aaa".

+ +

Copiando touch objects

+ +

Alguns browsers (mobile Safari, por exemplo) re-usa touch objects entre os eventos, por isso é melhor ter cuidado para copiar os bits, em vez de fazer referência a todo objeto.

+ +
function copyTouch(touch) {
+  return { identifier: touch.identifier, pageX: touch.pageX, pageY: touch.pageY };
+}
+ +

Encontrando um toque ongoing

+ +

A função ongoingTouchIndexById() abaixo verifica através do array ongoingTouches para encontrar o toque correspondente ao indentificador passado, então ele retorna o índice do touch no array.

+ +
function ongoingTouchIndexById(idToFind) {
+  for (var i=0; i < ongoingTouches.length; i++) {
+    var id = ongoingTouches[i].identifier;
+
+    if (id == idToFind) {
+      return i;
+    }
+  }
+  return -1;    // não econtrado
+}
+
+ +

Mostrando o que está acontecendo

+ +
function log(msg) {
+  var p = document.getElementById('log');
+  p.innerHTML = msg + "\n" + p.innerHTML;
+}
+ +

If your browser supports it, you can {{ LiveSampleLink('Example', 'see it live') }}.

+ +

jsFiddle example

+ +

Additional tips

+ +

This section provides additional tips on how to handle touch events in your web application.

+ +

Handling clicks

+ +

Since calling preventDefault() on a touchstart or the first touchmove event of a series prevents the corresponding mouse events from firing, it's common to call preventDefault() on touchmove rather than touchstart. That way, mouse events can still fire and things like links will continue to work. Alternatively, some frameworks have taken to refiring touch events as mouse events for this same purpose. (This example is oversimplified and may result in strange behavior. It is only intended as a guide.)

+ +
function onTouch(evt) {
+  evt.preventDefault();
+  if (evt.touches.length > 1 || (evt.type == "touchend" && evt.touches.length > 0))
+    return;
+
+  var newEvt = document.createEvent("MouseEvents");
+  var type = null;
+  var touch = null;
+  switch (evt.type) {
+    case "touchstart":    type = "mousedown";    touch = evt.changedTouches[0];break;
+    case "touchmove":        type = "mousemove";    touch = evt.changedTouches[0];break;
+    case "touchend":        type = "mouseup";    touch = evt.changedTouches[0];break;
+  }
+  newEvt.initMouseEvent(type, true, true, evt.originalTarget.ownerDocument.defaultView, 0,
+    touch.screenX, touch.screenY, touch.clientX, touch.clientY,
+    evt.ctrlKey, evt.altKey, evt.shirtKey, evt.metaKey, 0, null);
+  evt.originalTarget.dispatchEvent(newEvt);
+}
+
+ +

Calling preventDefault() only on a second touch

+ +

One technique for preventing things like pinchZoom on a page is to call preventDefault() on the second touch in a series. This behavior is not well defined in the touch events spec, and results in different behavior for different browsers (i.e., iOS will prevent zooming but still allow panning with both fingers; Android will allow zooming but not panning; Opera and Firefox currently prevent all panning and zooming.) Currently, it's not recommended to depend on any particular behavior in this case, but rather to depend on meta viewport to prevent zooming.

+ +
+
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome("22.0") }}{{ CompatGeckoDesktop("18.0") }}
+ Disabled with 24 ({{ bug(888304) }})
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}(Yes){{ CompatGeckoMobile("6.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Gecko notes

+ +

The dom.w3c_touch_events.enabled tri-state preference can be used to disable (0), enable (1), and auto-detect(2) support for standard touch events; by default, they're on auto-detect(2). After changing the preference, you must restart the browser for the changes to take effect.

+ +
+

Prior to {{Gecko("12.0")}}, Gecko did not support multi-touch; only one touch at a time was reported.

+
+ +
+

Note: As of {{Gecko("24.0")}}, the touch events support introduced with {{Gecko("18.0")}} has been disabled on the desktop version of Firefox, as some popular sites including Google and Twitter are not working properly. Once the bug is fixed, the API will be enabled again. To enable it anyway, open about:config and set the dom.w3c_touch_events.enabled pref to 2. The mobile versions including Firefox for Android and Firefox OS are not affected by this change. Also, the API has been enabled on the Metro-style version of Firefox for Windows 8.

+
+ +
Note: Prior to {{Gecko("6.0") }}, Gecko offered a proprietary touch event API. That API is now deprecated; you should switch to this one.
-- cgit v1.2.3-54-g00ecf