1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
---
title: WindowOrWorkerGlobalScope.setTimeout
slug: Web/API/setTimeout
tags:
- API
- HTML DOM
- WindowOrWorkerGlobalScope
- setTimeout
translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout
original_slug: Web/API/WindowOrWorkerGlobalScope/setTimeout
---
<div>{{APIRef("HTML DOM")}}</div>
<p>El método <strong><code>setTimeout()</code></strong> del mixin {{domxref("WindowOrWorkerGlobalScope")}} establece un temporizador que ejecuta una función o una porción de código después de que transcurre un tiempo establecido.</p>
<h2 id="Syntax" name="Syntax">Sintaxis</h2>
<pre class="syntaxbox"><em>var idTemporizador</em> = <em>scope</em>.setTimeout(<em>funcion</em>[, <em>retraso</em>, <em>parametro1</em>, <em>parametro2</em>, ...]);
<em>var</em> <em>idTimeout</em> = <em>scope</em>.setTimeout(<em>funcion</em>[, <em>retraso</em>]);
<em>var idTimeout</em> = <em>scope</em>.setTimeout(<em>codigo</em>[, <em>retraso</em>]);
</pre>
<h3 id="Parámetros">Parámetros</h3>
<dl>
<dt><code>funcion</code></dt>
<dd>Una {{jsxref("function")}} para ejecutar después de que expire el temporizador.</dd>
<dt><code>codigo</code></dt>
<dd>Una sintaxis opcional que le permite incluir una cadena en lugar de una función, la cual es compilada y ejecutada cuando el temporizador expira. Esta sintaxis <strong>no se recomienda</strong> por las mismas razones que hacen del uso de {{jsxref("Global_Objects/eval", "eval()")}} un riesgo de seguridad.</dd>
<dt><code>retraso</code> {{optional_inline}}</dt>
<dd>Tiempo, en milisegundos (milésimas de segundo), que el temporizador debe esperar antes de ejecutar la función o el código. Si se omite este parámetro se usa el valor 0. Tenga en cuenta que el retraso real puede ser más prolongado; ver más abajo {{anch("Reasons for delays longer than specified")}}.</dd>
<dt><code>param1, ..., paramN</code> {{optional_inline}}</dt>
<dd>Parámetros adicionales que se pasan a la función especificada por <em>func</em> una vez el temporizador expira.</dd>
</dl>
<div class="note"><strong>Nota:</strong> Pasar parámetros adicionales a la función en la primera sintaxis no funciona en Internet Explorer 9 o inferior. Si quiere habilitar esta funcionalidad en ese navegador, debe usar un código de compatibilidad (vea la sección <a href="#Callback_arguments">Callback arguments</a>).</div>
<h3 id="Valor_retornado">Valor retornado</h3>
<p>El valor retornado <code>IDtemporizador</code> es númerico y no es cero; identifica el temporizador creado con la llamada a <code>setTimeout()</code>; este valor puede pasarse a {{domxref("WindowOrWorkerGlobalScope.clearTimeout()")}} para cancelar el temporizador.</p>
<p>Puede ser útil advertir que <code>setTimeout()</code> y {{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}} comparten la misma piscina de IDs, y que tanto <code>clearTimeout()</code> como {{domxref("WindowOrWorkerGlobalScope.clearInterval", "clearInterval()")}} pueden intercambiarse. Por claridad, sin embargo, debe hacerlos coincidir para evitar confusiones cuando mantenga su código.</p>
<h2 id="Example" name="Example">Ejemplo</h2>
<p>El siguiente ejemplo establece dos botenes simples en una página web y los engancha a las rutinas <code>setTimeout()</code> y <code>clearTimeout()</code>. Presionando el primer botón establecerá un temporizador que llama un diálogo de alerta después de dos segundos y guarda el id del temporizador para usarlo con <code>clearTimeout()</code>. Opcionalmente puede cancelar este temporizador presionando el segundo botón.</p>
<h3 id="Contenido_HTML">Contenido HTML</h3>
<pre class="brush: html"><p>Ejemplo funcional</p>
<button onclick="delayedAlert();">Muestra una caja de alerta después de dos segundos</button>
<p></p>
<button onclick="clearAlert();">Cancela la alerta antes de que ocurra</button>
</pre>
<h3 id="Contenido_JavaScript">Contenido JavaScript</h3>
<pre class="brush: js">var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(slowAlert, 2000);
}
function slowAlert() {
alert("That was really slow!");
}
function clearAlert() {
window.clearTimeout(timeoutID);
}
</pre>
<p>{{ EmbedLiveSample('Example') }}</p>
<p>Vea también <a href="/en-US/docs/DOM/window.clearTimeout#Example" title="en-US/docs/DOM/window.clearTimeout#Example"><code>clearTimeout()</code> example</a>.</p>
<h2 id="Callback_arguments">Callback arguments</h2>
<p>Si necesita pasar un argumento a su función callback, pero necesita que funcione en Internet Explorer, que no soporta el envío de parámetros adicionales (ni con <code>setTimeout()</code> o <code>setInterval()</code>) usted puede incluir este código de compatibilidad <em>IE-specific</em> que habilitará la funcionalidad estándar de HTML5 para pasar los parámetros adicionales en ese navegador para ambos temporizadores solamente insertandolo al inicio de sus scripts.</p>
<pre class="brush: js">/*\
|*|
|*| IE-specific polyfill which enables the passage of arbitrary arguments to the
|*| callback functions of JavaScript timers (HTML5 standard syntax).
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
|*|
|*| Syntax:
|*| var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
|*| var timeoutID = window.setTimeout(code, delay);
|*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
|*| var intervalID = window.setInterval(code, delay);
|*|
\*/
if (document.all && !window.setTimeout.isPolyfill) {
var __nativeST__ = window.setTimeout;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setTimeout.isPolyfill = true;
}
if (document.all && !window.setInterval.isPolyfill) {
var __nativeSI__ = window.setInterval;
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setInterval.isPolyfill = true;
}
</pre>
<h2 id="Arreglo_solo_para_IE">Arreglo solo para IE</h2>
<p>Si quiere una solución completamente no intrusiva con otros navegadores móviles o de escritorio, incluyendo IE 9 y superior, puede usar los comentarios condicionales de JavaScript:</p>
<pre class="brush: js">/*@cc_on
// conditional IE < 9 only fix
@if (@_jscript_version <= 6)
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
@end
@*/
</pre>
<p>O usar un enfoque más limpio basado en el condicional para IE de HTML:</p>
<pre class="brush: html"><!--[if lt IE 9]><script>
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){
var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
});
</script><![endif]-->
</pre>
<p>Otra posibilidad es usar una función anónima para llamar el callback, pero esta solución es un poco más costosa. Ejemplo:</p>
<pre class="brush: js">var intervalID = setTimeout(function() { myFunc("uno", "dos", "tres"); }, 1000);
</pre>
<p>Sin embargo, otra posibilidad es usar <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind" title="/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind">function's bind</a>. Ejemplo:</p>
<pre class="brush: js">setTimeout(function(arg1){}.bind(undefined, 10));
</pre>
<h2 id="El_problema_this">El problema "<code>this</code>"</h2>
<p>Cuando pasa un método a <code>setTimeout()</code> (o cualquier otra función , por el estilo), podría ser invocada con el valor de <code>this</code> equivocado. Este problema es explicado en detalle en la <a href="/en-US/docs/JavaScript/Reference/Operators/this#Method_binding" title="en-US/docs/Core_JavaScript_1.5_Reference/Operators/Special_Operators/this_Operator#Method_binding">referencia de JavaScript</a>.</p>
<h3 id="Explicación">Explicación</h3>
<p>El código ejecutado por <code>setTimeout()</code> corre en un contexto de ejecución diferente al de la función por la que fue llamado. Como consecuencia, la palabra clave <code>this para la función llamada </code>será asignado al objeto <code>window</code> (o <code>global</code>); no tendrá el mismo valor del <code>this</code> de la función que llamó al <code>setTimeout</code>. Vea el siguiente ejemplo:</p>
<pre class="brush: js">myArray = ["cero", "uno", "dos"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // imprime "cero,uno,dos"
myArray.myMethod(1); // imprime "uno"
setTimeout(myArray.myMethod, 1000); // imprime "[object Window]" después de 1 segundo
setTimeout(myArray.myMethod, 1500, "1"); // imprime "undefined" después de 1.5 segundos
// intentemos pasar el objeto 'this'
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // mismo error</pre>
<p>Como puedes ver no hay forma de pasar el objeto <code>this</code> a la función callback.</p>
<h3 id="Una_posible_solución">Una posible solución</h3>
<p>Una posible forma de resolver el problema del "<code>this</code>" es reemplazar las dos funciones globales nativas <code>setTimeout()</code> or <code>setInterval()por dos no-nativas<em> </em> </code>que permitan su invocación a través del método <a href="en-US/docs/JavaScript/Reference/Global_Objects/Function/call" title="en-US/docs/JavaScript/Reference/Global_Objects/Function/call"><code>Function.prototype.call</code></a>. El siguiente ejemplo muestra un posible reemplazo:</p>
<pre class="brush: js">// Enable the passage of the 'this' object through the JavaScript timers
var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};</pre>
<div class="note"><strong>Nota:</strong> Estos dos reemplazos habilitarán el estándar HTML5 para el paso de argumentos arbitrarios a las funciones callback de los temporizadores en IE. Pueden usarse como polyfills también. Vea el párrafo <a href="#Callback_arguments">Callback arguments</a>.</div>
<p>Prueba de la nueva característica:</p>
<pre class="brush: js">myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds
</pre>
<p>No hay soluciones nativas <em>ad hoc</em> a este problema.</p>
<div class="note"><strong>Nota:</strong> JavaScript 1.8.5 introduce el método <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind" title="en-US/docs/JavaScript/Reference/Global Objects/Function/bind">Function.prototype.bind(</a></code>, que permite especificar el valor que debería usarse como <code>this</code> para todas las llamadas a una función dada. Esto permite evitar fácilmente los problemas en los que no es claro que será, dependiendo del contexto desde el cual la función sea llamada.</div>
<h2 id="Notas">Notas</h2>
<p>Puede cancelar el temporizador usando <code><a href="/en-US/docs/DOM/window.clearTimeout" title="en-US/docs/DOM/window.clearTimeout">window.clearTimeout()</a></code>. Si desea tener una función llamada repetidamente (p.e., cada N milisegundos), considere usar <code><a href="/en-US/docs/DOM/window.setInterval" title="en-US/docs/DOM/window.setInterval">window.setInterval()</a></code>.</p>
<p>Es importante notar que la función o fragmento de código no puede ser ejecutado hasta que el hilo que llamó <code>setTimeout()</code>haya terminado.</p>
<h3 id="Pasando_cadenas_literales">Pasando cadenas literales</h3>
<p>Pasando una cadena en vez de una función a <code>setTimeout()</code>pasa lo mismo que al usar <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/eval#Don.27t_use_eval.21" title="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval">eval</a>. </code></p>
<pre class="brush: js">// Correcto
window.setTimeout(function() {
alert("Hello World!");
}, 500);
// Incorrecto
window.setTimeout("alert(\"Hello World!\");", 500);
</pre>
<p>Las cadenas literales son evaluadas en el contexto global, así que los símbolos locales en el contexto donde <code>setTimeout()</code> fue llamado no estarán disponibles cuando la cadena es evaluada como código.</p>
<h3 id="Minimum_maximum_delay_and_timeout_nesting">Minimum/ maximum delay and timeout nesting</h3>
<p><a class="external" href="http://code.google.com/p/chromium/issues/detail?id=792#c10">Historically</a> browsers implement <code>setTimeout()</code> "clamping": successive <code>setTimeout()</code> calls with <code>delay</code> smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, <code>DOM_MIN_TIMEOUT_VALUE</code>, is 4 ms (stored in a preference in Firefox: <code>dom.min_timeout_value</code>), with a <code>DOM_CLAMP_TIMEOUT_NESTING_LEVEL</code> of 5ms.</p>
<p>In fact, 4ms is <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers">specified by the HTML5 spec</a> and is consistent across browsers released in 2010 and onward. Prior to {{ geckoRelease("5.0") }}, the minimum timeout value for nested timeouts was 10 ms.</p>
<p>In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.</p>
<p>To implement a 0 ms timeout in a modern browser, you can use {{ domxref("window.postMessage()") }} as <a class="external" href="http://dbaron.org/log/20100309-faster-timeouts">described here</a>.</p>
<p>Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.</p>
<h4 id="Inactive_tabs">Inactive tabs</h4>
<p>In {{ geckoRelease("5.0") }} and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see {{ bug(633421) }} for more information about this in Mozilla or <a class="external" href="http://crbug.com/66078">crbug.com/66078</a> for details about this in Chrome.</p>
<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>1.0</td>
<td>{{ CompatGeckoDesktop("1") }}</td>
<td>4.0</td>
<td>4.0</td>
<td>1.0</td>
</tr>
<tr>
<td>Soporta parámetros para callback*1</td>
<td>{{ CompatVersionUnknown }}</td>
<td>{{ CompatVersionUnknown }}</td>
<td>10.0</td>
<td>{{ CompatVersionUnknown }}</td>
<td>{{ CompatUnknown }}</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>1.0</td>
<td>1.0</td>
<td>{{ CompatGeckoMobile("1") }}</td>
<td>6.0</td>
<td>6.0</td>
<td>1.0</td>
</tr>
<tr>
<td>Soporta parámetros para callback*1</td>
<td>{{ CompatUnknown }}</td>
<td>{{ CompatUnknown }}</td>
<td>{{ CompatUnknown }}</td>
<td>{{ CompatUnknown }}</td>
<td>{{ CompatUnknown }}</td>
<td>{{ CompatUnknown }}</td>
</tr>
</tbody>
</table>
</div>
<p>*1 Whether it supports the optional parameters when in its first form or not.</p>
<h2 id="Specification" name="Specification">Especificación</h2>
<p>Parte del DOM nivel 0, como se especifica en <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#timers">HTML5</a>.</p>
<h2 id="See_also" name="See_also">Vea también</h2>
<ul>
<li><a href="/en-US/docs/JavaScript/Timers" title="/en-US/docs/JavaScript/Timers">JavaScript timers</a></li>
<li><a href="/en-US/docs/Mozilla/JavaScript_code_modules/Timer.jsm" title="/en-US/docs/Mozilla/JavaScript_code_modules/Timer.jsm">Timer.jsm</a></li>
<li>{{domxref("window.setInterval")}}</li>
<li>{{domxref("window.requestAnimationFrame")}}</li>
<li><a href="/en-US/docs/JavaScript/Timers/Daemons" title="/en-US/docs/JavaScript/Timers/Daemons"><em>Daemons</em> management</a></li>
</ul>
|