diff options
Diffstat (limited to 'files/es/dom/touch_events/index.html')
-rw-r--r-- | files/es/dom/touch_events/index.html | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/files/es/dom/touch_events/index.html b/files/es/dom/touch_events/index.html new file mode 100644 index 0000000000..02a4a4eacb --- /dev/null +++ b/files/es/dom/touch_events/index.html @@ -0,0 +1,292 @@ +--- +title: Eventos de toque +slug: DOM/Touch_events +tags: + - DOM + - Event + - Mobile + - NeedsMobileBrowserCompatTable + - eventos +translation_of: Web/API/Touch_events +--- +<p>Con el fin de proporcionar soporte de calidad para usuarios de interfaces táctiles, los eventos táctiles dan la posibilidad de interpretar la actividad de los dedos en pantallas táctiles o trackpads.</p> + +<h2 id="Definiciones">Definiciones</h2> + +<dl> + <dt>Superficie</dt> + <dd>La superficie sensible al tacto. Esta puede ser una pantalla o un trackpad.</dd> +</dl> + +<dl> + <dt><strong style="font-weight: bold;">Punto de toque</strong></dt> + <dd>Un punto de contacto con la superficie. Esto podría ser un dedo (o un codo, oreja, nariz, o lo que sea, pero probablemente un dedo) o un stylus.</dd> +</dl> + +<h2 id="Interfaces">Interfaces</h2> + +<dl> + <dt>{{ domxref("TouchEvent") }}</dt> + <dd>Representa un evento que ocurre cuando el estado de los toques en la superficie cambian.</dd> + <dt>{{ domxref("Touch") }}</dt> + <dd>Represeta un único punto de contacto entre el usuario y la superficie táctil.</dd> + <dt>{{ domxref("TouchList") }}</dt> + <dd>Representa varios puntos de toque: esto se utiliza cuando el usuario tiene, por ejemplo, varios dedos en la superficie al mismo tiempo.</dd> + <dt>{{ domxref("DocumentTouch") }}</dt> + <dd>Contiene varios métodos para crear objetos de {{domxref("Touch")}} y {{domxref("TouchList")}}.</dd> +</dl> + +<h2 id="Ejemplo">Ejemplo</h2> + +<p>Este ejemplo muestra múltiples puntos de toques al mismo tiempo, permitiendo al usuario dibujar en un {{ HTMLElement("canvas") }} con más de un dedo a la vez. Esto funciona solamente en un navegador que soporte eventos táctiles.</p> + +<div class="note"><strong>Not</strong><strong>a:</strong> El texto de abajo usa el término "dedo" cuando describe el contacto con la superficie, pero esto podría ser, por supuesto, también un stylus u otro método de contacto.</div> + +<h3 id="Configurando_los_eventos_de_manipulación">Configurando los eventos de manipulación</h3> + +<p>Cuando la página carga, la función <code>startup()</code> mostrada a continuación es llamada por nuestro atributo <code>onload</code> del elemento {{ HTMLElement("body") }}.</p> + +<pre class="brush: js">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", handleLeave, false); + el.addEventListener("touchmove", handleMove, false); +} +</pre> + +<p>Esto simplemente configura todos los detectores de eventos para nuestro elemento {{ HTMLElement("canvas") }}, por lo que podremos manejar todos los eventos de toque cuando se produzcan.</p> + +<h3 id="Seguimiento_de_nuevos_toques">Seguimiento de nuevos toques</h3> + +<p>Cuando un evento <code>touchstart</code> ocurre, indicando que un nuevo toque sobre la superficie se ha producido, la función <code>handleStart()</code> de a continuación es llamada.</p> + +<pre class="brush: js">function handleStart(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++) { + ongoingTouches.push(touches[i]); + var color = colorForTouch(touches[i]); + ctx.fillStyle = color; + ctx.fillRect(touches[i].pageX-2, touches[i].pageY-2, 4, 4); + } +} +</pre> + +<p>Esto llama a {{ domxref("event.preventDefault()") }} para mantener al navegador procesando el evento de toque (esto también previene que un evento del ratón o mouse sea entregado). Entonces obtenemos el contexto y lanzamos la lista de puntos de contacto cambiados de la propiedad {{ domxref("TouchEvent.changedTouches") }} del evento.</p> + +<p>Después de ello, iteramos sobre todos los objetos {{ domxref("Touch") }} de la lista, insertándolo en una matriz de puntos de toque activos y dibujando el punto de inicio como un pequeño rectángulo; estamos usando una línea de 4 pixeles de ancho, por tanto estamos dibujando un cuadrado de 4 por 4 píxeles como punto de consistencia.</p> + +<h3 id="Dibujando_mientras_los_eventos_de_toque_se_mueven">Dibujando mientras los eventos de toque se mueven</h3> + +<p>Cada vez que uno o más dedos se mueven, un evento <code>touchmove</code> es entregado, resultando en una llamada a nuestra función <code>handleMove()</code>. Su responsabilidad en este ejemplo es actualizar la información de toque cacheada y dibujar una línea desde la posición previa a la posición actual en cada toque.</p> + +<pre class="brush: js">function handleMove(evt) { + evt.preventDefault(); + var el = document.getElementsByTagName("canvas")[0]; + var ctx = el.getContext("2d"); + var touches = evt.changedTouches; + + ctx.lineWidth = 4; + + for (var i=0; i<touches.length; i++) { + var color = colorForTouch(touches[i]); + var idx = ongoingTouchIndexById(touches[i].identifier); + + ctx.fillStyle = color; + ctx.beginPath(); + ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY); + ctx.lineTo(touches[i].pageX, touches[i].pageY); + ctx.closePath(); + ctx.stroke(); + ongoingTouches.splice(idx, 1, touches[i]); // swap in the new touch record + } +} +</pre> + +<p>Esto se repite también en los toques cambiados, pero mira en nuestra matriz de información de toques cacheados la información previa de cada toque con el fin de determinar los puntos de inicio para cada nuevo segmento de línea de toques que será dibujada. Esto se hace mirando cada propiedad de los toques de {{ domxref("Touch.identifier") }} . Esta propiedad es un único entero para cada toque, y sigue siendo consistente para cada evento durante la duración del contacto de cada dedo con la superficie.</p> + +<p>Esto nos permite conseguir las coordenadas de la posición previa de cada toque y usar el método apropiado de contexto para dibujar un segmento de línea uniendo dos posiciones a la vez.</p> + +<p>Después de dibujar la línea, llamamos a <a href="/en/JavaScript/Reference/Global_Objects/Array/splice" title="en/JavaScript/Reference/Global Objects/Array/splice"><code>Array.splice()</code></a> para reemplazar la información previa sobre el punto de toque con la información actual de la matriz <code>ongoingTouches</code>.</p> + +<h3 id="Manejando_el_final_de_un_toque">Manejando el final de un toque</h3> + +<p>Cuando el usuario levanta un dedo de la superficie, un evento <code>touchend</code> es enviado. De igual manera, si el dedo se desliza fuera de nuestro lienzo, obtenemos un evento <code>touchleave</code>. Manejamos ambos casos de la misma manera: llamando a la función <code>handleEnd()</code> de abajo. Su trabajo es dibujar el último segmento de línea para cada toque que ha finalizado y remueve el punto de toque de la lista de toques en marcha.</p> + +<pre class="brush: js">function handleEnd(evt) { + evt.preventDefault(); + var el = document.getElementsByTagName("canvas")[0]; + var ctx = el.getContext("2d"); + var touches = evt.changedTouches; + + ctx.lineWidth = 4; + + for (var i=0; i<touches.length; i++) { + var color = colorForTouch(touches[i]); + var idx = ongoingTouchIndexById(touches[i].identifier); + + ctx.fillStyle = color; + ctx.beginPath(); + ctx.moveTo(ongoingTouches[i].pageX, ongoingTouches[i].pageY); + ctx.lineTo(touches[i].pageX, touches[i].pageY); + ongoingTouches.splice(i, 1); // remove it; we're done + } +} +</pre> + +<p>Esto es muy similar a la función previa; la única diferencia real es que cuando llamamos a <a href="/en/JavaScript/Reference/Global_Objects/Array/splice" title="en/JavaScript/Reference/Global Objects/Array/splice"><code>Array.splice()</code></a>, simplemente remueve la antigua entrada de la lista de toques en marcha, sin añadir la información actualizada. El resultado es que detenemos el seguimiento del punto de toque.</p> + +<h3 id="Manejando_los_toques_cancelados">Manejando los toques cancelados</h3> + +<p>Si el dedo del usuario se equivoca en la Interfaz del navegador, o el toque necesita ser cancelado, el evento <code>touchcancel</code> es enviado, y llamamos a la función <code>handleCancel()</code> abajo.</p> + +<pre class="brush: js">function handleCancel(evt) { + evt.preventDefault(); + var touches = evt.changedTouches; + + for (var i=0; i<touches.length; i++) { + ongoingTouches.splice(i, 1); // remove it; we're done + } +} +</pre> + +<p>Dado que la idea es cancelar el toque inmediatamente, simplemente lo removemos de la lista de toques en marcha sin dibujar un segmento de línea final.</p> + +<h3 id="Funciones_de_conveniencia">Funciones de conveniencia</h3> + +<p>Este ejemplo usa dos funciones de convenience que deben mirarse brevemente para ayudar a que el resto del código sea más claro.</p> + +<h4 id="Seleccionando_un_color_para_cada_toque">Seleccionando un color para cada toque</h4> + +<p>Con el fin de hacer que cada dibujo de toque se vea diferente, la función <code>colorForTouch()</code> es usada para elegir un color basado en el identificador único de toque. Este identificador estará siempre entre 0 y un valor menos que el número de toques activos. Puesto que es muy improbable que alguna persona con más de 16 dedos use este demo, convertimos estos directamente en colores de escalas grises.</p> + +<pre class="brush: js">function colorForTouch(touch) { + var id = touch.identifier; + id = id.toString(16); // make it a hex digit + return "#" + id + id + id; +} +</pre> + +<p>El resultado de esta función es un string o cadena que puede ser usada cuando se llame a funciones {{ HTMLElement("canvas") }} para configurar los colores de dibujos. Por ejemplo, para un valor {{ domxref("Touch.identifier") }} de 10, el resultado string o cadena es "#aaa".</p> + +<h4 id="Encontrando_un_toque_continuo">Encontrando un toque continuo</h4> + +<p>La función <code>ongoingTouchIndexById()</code> abajo explora mediante la matriz <code>ongoingTouches</code> para encontrar el toque que coincida con el identificador dado, luego devuelve los índices de toques a la matriz.</p> + +<pre class="brush: js">function ongoingTouchIndexById(idToFind) { + for (var i=0; i<ongoingTouches.length; i++) { + var id = ongoingTouches[i].identifier; + + if (id == idToFind) { + return i; + } + } + return -1; // not found +} +</pre> + +<p><a href="/samples/domref/touchevents.html">Ver ejemplo en vivo</a></p> + +<h2 id="Consejos_adicionales">Consejos adicionales</h2> + +<p>Esta sección provee consejos adicionales sobre como manejar los eventos de toques en tu aplicación web.</p> + +<h3 id="Manejando_los_clics">Manejando los clics</h3> + +<p>Ya que la llamada <code>preventDefault()</code> en un <code>touchstart</code> o el primer evento <code>touchmove</code> de una serie impide que los eventos correspondientes eventos del mouse o ratón se disparen, es común llamar a <code>preventDefault()</code> en <code>touchmove</code> en lugar de <code>touchstart</code>. De esta manera, los eventos del ratón pueden todavía ser disparados y cosas como enlaces siguen funcionando. Alternativamente, algunos frameworks tienen que referirse a eventos de toque como eventos de ratón para este mismo propósito. (Este ejemplo es muy simplificado y podria resultar en un extraño comportamiento. Solo se diseñó como guía).</p> + +<pre class="brush: js">function onTouch(evt) { + evt.preventDefault(); + if (evt.touches.length > 1 || (evt.type == "touchend" && evt.touches.length > 0)) + return; + + var newEvt = <a href="https://developer.mozilla.org/en/DOM/document.createEvent" rel="internal" title="en/DOM/document.createEvent">document.createEvent</a>("MouseEvents"); + var type = null; + var touch = null; + switch (event.type) { + case "touchstart": type = "mousedown"; touch = event.changedTouches[[0]; + case "touchmove": type = "mousemove"; touch = event.changedTouches[[0]; + case "touchend": type = "mouseup"; touch = event.changedTouches[0]; + } + newEvt.<strong>initMouseEvent</strong>(type, true, true, event.<code><a href="https://developer.mozilla.org/en/DOM/event.originalTarget" rel="custom">originalTarget</a>.ownerDocument.defaultView</code>, 0, + touch.screenX, touch.screenY, touch.clientX, touch.clientY, + evt.ctrlKey, evt.altKey, evt.shirtKey, evt.metaKey, 0, null); + event.<code><a href="https://developer.mozilla.org/en/DOM/event.originalTarget" rel="custom">originalTarget</a></code>.<a href="https://developer.mozilla.org/en/DOM/element.dispatchEvent" rel="internal" title="en/DOM/element.dispatchEvent">dispatchEvent</a>(newEvt); +} +</pre> + +<h3 id="Llamando_a_preventDefault()_solo_en_un_segundo_toque">Llamando a preventDefault() solo en un segundo toque</h3> + +<p>Una cosa para prevenir cosas como <code>pinchZoom</code> en una página es llamar a <code>preventDefault()</code> en el segundo toque de una serie. Este comportamiento no está bien definido en los eventos de toque, y resulta en diferentes comportamientos en diferentes navegadores (osea iOS evitará el zoom o acercamiento pero permitirá vista panorámica con ambos dedos. Android permitirá zoom o acercamiento pero no una panorámica. Opera and Firefox actualmente evita panorámica y zoom o acercamiento). Actualmente, no se recomienda depender de ningún comportamiento en particular en este caso, si no mas bien depender de una meta vista para evitar el zoom.</p> + +<dl> +</dl> + +<h2 id="Compatibilidad_de_navegadores">Compatibilidad de navegadores</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Característica</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>{{ CompatChrome("22.0") }}</td> + <td>{{ CompatGeckoDesktop("18.0") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Característica</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatGeckoMobile("6.0") }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<h3 id="Notas_de_Gecko">Notas de Gecko</h3> + +<p>La preferencia <code>dom.w3c_touch_events.enabled</code> puede ser utilizada para activar o desactivar el soporte de eventos de toque estándares; por defecto, están activados.</p> + +<div class="geckoVersionNote" style=""> +<p>{{ gecko_callout_heading("12.0") }}</p> + +<p>Antes de Gecko 12.0 {{ geckoRelease("12.0") }}, Gecko no soportaba multi-toques; solo un toque cada vez era reportado.</p> +</div> + +<div class="note"><strong>Note: </strong>Antes de Gecko 6.0 {{ geckoRelease("6.0") }}, Gecko ofrecía una <a href="/en/DOM/Touch_events_(Mozilla_experimental)" title="en/DOM/Touch events (Mozilla experimental)">API de eventos de toque propietaria</a>. Está API está obsoleta actualmente; deberías cambiar a esta."</div> |