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
|
---
title: Page Visibility API
slug: Web/API/Page_Visibility_API
tags:
- API
- DOM
- Intermediário
- Tutoriais
translation_of: Web/API/Page_Visibility_API
---
<div>{{DefaultAPISidebar("Page Visibility API")}}</div>
<p><span class="seoSummary">A <strong>Page Visibility API</strong> </span>permite-lhe saber quando uma página da <em>Web </em>está visível ou em foco. Com a navegação por separadores, existe uma chance razoável de que qualquer página da <em>Web </em>esteja em segundo plano e, portanto, não seja visível para o utilizador. Quando o utilizador minimiza a página da <em>Web </em>ou move-se para outro separador, a API envia um evento {{event('visibilitychange')}} sobre a visibilidade da página. Pode detetar o evento e executar algumas ações ou comportar-se de forma diferente. Por exemplo, se a sua aplicação da <em>Web </em>estiver a reproduzir um vídeo, esta pausará o momento em que o utilizador olha para outro navegador, e reproduz novamente quando o utilizador volta ao separador. O utilizador não perde o seu lugar no vídeo e pode continuar a assistir.</p>
<p>Estados de visibilidade de uma {{HTMLElement("iframe")}} são iguais ao documento original. Ocultar a iframe com propriedades CSS não desencadeia eventos de visibilidade nem altera o estado do documento de conteúdo.</p>
<h3 id="Benefícios">Benefícios</h3>
<p>The API is particularly useful for saving resources by giving developers the opportunity to not perform unnecessary tasks when the webpage is not visible.</p>
<ul>
</ul>
<h3 id="Casos_de_utilização">Casos de utilização</h3>
<p>Alguns exemplos:</p>
<ul>
<li>A site has an image carousel that shouldn't advance to the next slide unless the user is viewing the page.</li>
<li>An application showing a dashboard of information doesn't want to poll the server for updates when the page isn't visible.</li>
<li>A page wants to detect when it is being prerendered so it can keep accurate count of page views.</li>
<li>A site wants to switch off sounds when a device is in standby mode (user pushes power button to turn screen off)</li>
</ul>
<p>Developers have historically used imperfect proxies to detect this. For example, registering an onblur/onfocus handler on the window helps you know when your page is not the active page, but it does not tell you that your page is hidden to the user. The Page Visibility API addresses this. (When compared with registering onblur/onfocus handlers on the window, a key difference is that a page does <em>not</em> become hidden when another window is made active and the browser window loses focus. A page only becomes hidden when the user switches to a different tab or minimizes the browser window.)</p>
<h3 id="Políticas_em_vigor_para_auxiliar_o_desempenho_da_página_de_fundo">Políticas em vigor para auxiliar o desempenho da página de fundo</h3>
<p>Along with the Page Visibility API, there are a number of policies in place to mitigate negative performance effects associated with background tabs:</p>
<ul>
<li>{{domxref("Window.requestAnimationFrame()")}} calls are paused in most browsers when running in background tabs or hidden {{ HTMLElement("iframe") }}s in order to improve performance and battery life.</li>
<li>Timers such as {{domxref("WindowOrWorkerGlobalScope.setTimeout")}} are throttled in background/inactive tabs to help improve performance. See <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified">Reasons for delays longer than specified</a> for more details.</li>
<li>Budget-based background timeout throttling is now available in modern browsers (Firefox 58+, Chrome 57+), placing an additional limit on background timer CPU usage. This operates in a similar way across modern browsers, with the details being as follows:
<ul>
<li>In Firefox, windows in background tabs each have their own time budget in milliseconds — a max and a min value of +50 ms and -150 ms, respectively. Chrome is very similar except that the budget is specified in seconds.</li>
<li>Windows are subjected to throttling after 30 seconds, with the same throttling delay rules as specified for window timers (again, see <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified">Reasons for delays longer than specified</a>.) In Chrome, this value is 10 seconds.</li>
<li>Timer tasks are only permitted when the budget is non-negative.</li>
<li>When a timer has executed, the execution time is deducted from the budget of the window where the timeout gets called from.</li>
<li>The budget regenerates at a rate of 10 ms per second, in both Firefox and Chrome.</li>
</ul>
</li>
<li>Some processes are exempt from this throttling behaviour:
<ul>
<li>Applications playing audio are considered foreground and aren’t throttled.</li>
<li>Applications with real-time connections (<a href="/en-US/docs/Web/API/WebSockets_API">WebSockets</a> and <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a>), to avoid closing these connections by timeout.</li>
<li><a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a> processes.</li>
</ul>
</li>
</ul>
<h2 id="Exemplo">Exemplo</h2>
<p>Ver <a href="http://daniemon.com/tech/webapps/page-visibility/">exemplo live </a>(vídeo com som).</p>
<p>O exemplo, que pausa o vídeo quando muda para outro separador e reproduz novamente quando volta ao seu separador, foi criado com o seguinte código:</p>
<pre class="brush: js">// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
var videoElement = document.getElementById("videoElement");
// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
if (document[hidden]) {
videoElement.pause();
} else {
videoElement.play();
}
}
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || typeof document.hidden === "undefined") {
console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change
document.addEventListener(visibilityChange, handleVisibilityChange, false);
// When the video pauses, set the title.
// This shows the paused
videoElement.addEventListener("pause", function(){
document.title = 'Paused';
}, false);
// When the video plays, set the title.
videoElement.addEventListener("play", function(){
document.title = 'Playing';
}, false);
}
</pre>
<h2 id="Resumo_das_propriedades">Resumo das propriedades</h2>
<dl>
<dt>
<p id="document.hidden_Read_only">{{domxref("document.hidden")}} <span class="inlineIndicator readOnly readOnlyInline" title="This value may not be changed.">Read only </span></p>
</dt>
<dd>
<p>Returns <code>true</code> if the page is in a state considered to be hidden to the user, and <code>false</code> otherwise.</p>
</dd>
<dt>
<p id="document.visibilityState_Read_only">{{domxref("document.visibilityState")}} <span class="inlineIndicator readOnly readOnlyInline" title="This value may not be changed.">Read only </span></p>
</dt>
<dd>
<p>Is a <code>string</code> denoting the visibility state of the document. Possible values:</p>
<ul>
<li><code>visible</code> : the page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.</li>
<li><code>hidden</code> : the page content is not visible to the user. In practice this means that the document is either a background tab or part of a minimized window, or the OS screen lock is active.</li>
<li><code>prerender</code> : the page content is being prerendered and is not visible to the user (considered hidden for purposes of <code>document.hidden</code>). The document may start in this state, but will never transition to it from another value. Note: browser support is optional.</li>
<li><code>unloaded</code> : the page is being unloaded from memory. Note: browser support is optional.</li>
</ul>
<pre class="brush: js">//startSimulation and pauseSimulation defined elsewhere
function handleVisibilityChange() {
if (document.hidden) {
pauseSimulation();
} else {
startSimulation();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
</pre>
</dd>
<dt>
<p>{{domxref("document.onvisibilitychange")}}</p>
</dt>
<dd>
<p>Is an {{domxref("EventHandler")}} representing the code to be called when the {{event("visibilitychange")}} event is raised.</p>
</dd>
</dl>
<h2 id="Especificações">Especificações</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Especificação</th>
<th scope="col">Estado</th>
<th scope="col">Comentário</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('Page Visibility API')}}</td>
<td>{{Spec2('Page Visibility API')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidade_de_navegador">Compatibilidade de navegador</h2>
<div>{{CompatibilityTable}}</div>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Funcionalidade</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari (WebKit)</th>
</tr>
<tr>
<td>Suporte básico</td>
<td>13 {{property_prefix("webkit")}}<br>
33</td>
<td>{{CompatGeckoDesktop(18)}}<sup>[2]</sup></td>
<td>10</td>
<td>12.10<sup>[1]</sup></td>
<td>7</td>
</tr>
<tr>
<td><code>onvisibilitychange</code></td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatGeckoDesktop(56)}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
<tr>
<td>Budget-based background timeout throttling</td>
<td>57</td>
<td>{{CompatGeckoDesktop(58)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Funcionalidade</th>
<th>Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>IE Phone</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Suporte básico</td>
<td>5.0<sup>[3]</sup></td>
<td>{{CompatGeckoMobile(18)}}<sup>[2]</sup></td>
<td>10</td>
<td>12.10<sup>[1]</sup></td>
<td>7<sup>[4]</sup></td>
</tr>
<tr>
<td><code>onvisibilitychange</code></td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatGeckoMobile(56)}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
<tr>
<td>Budget-based background timeout throttling</td>
<td>{{CompatNo}}</td>
<td>{{CompatGeckoMobile(58)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatVersionUnknown}}</td>
<td>{{CompatVersionUnknown}}</td>
</tr>
</tbody>
</table>
</div>
<p>[1] Doesn't fire the {{event("visibilitychange")}} event when the browser window is minimized, nor set <code>hidden</code> to <code>true</code>.</p>
<p>[2] From Firefox 10 to Firefox 51 included, this property could be used prefixed with <code>moz</code>.</p>
<p>[3] Android 4.4 supports this feature if prefixed with <code>webkit</code>.</p>
<p>[4] From iOS 11.0.2 onwards, the values are not correct in standalone mode (when you press "Add to Homescreen") and when the screen is locked (you pressed the power button). The value for <code>hidden</code> is <code>false</code> and <code>visibilityState</code> is <code>visible</code>.</p>
<h2 id="Consultar_também">Consultar também</h2>
<ul>
<li>Descrição da <a href="http://blogs.msdn.com/b/ie/archive/2011/07/08/using-pc-hardware-more-efficiently-in-html5-new-web-performance-apis-part-2.aspx" title="Page Visibility on IEBlog">Page Visibility API</a> no IEBlog (inglês).</li>
<li>Descrição da <a href="http://code.google.com/chrome/whitepapers/pagevisibility.html" title="Page Visibility API by Google">Page Visibility API</a> pela Google (inglês).</li>
</ul>
|