安全上下文
此特征只可用于
安全上下文
(HTTPS),在某些或所有
支持浏览器
.
这是
实验性技术
检查
浏览器兼容性表格
要小心谨慎在生产中使用这之前。
The Presentation API lets a 用户代理 (such as a Web browser) effectively display web content through large presentation devices such as projectors and network-connected televisions. Supported types of multimedia devices include both displays which are wired using HDMI, DVI, or the like, or wireless, using DLNA , Chromecast , AirPlay ,或 Miracast .
In general, a web page uses the Presentation Controller API to specify the web content to be rendered on presentation device and initiate the presentation session. With Presentation Receiver API, the presenting web content obtains the session status. With providing both the controller page and the receiver one with a messaged-based channel, a Web developer can implement the interaction between these two pages.
Depending on the connection mechanism provided by the presentation device, any controller- and receiver page can be rendered by the same user agent, or by separated user agents.
Presentation
Presentation
interface provides a mechanism to override the browser default behavior of launching presentation to external screen. In receiving browsing context,
Presentation
interface provides the access to the available presentation connections.
PresentationRequest
Initiates or reconnects to a presentation made by a controlling browsing context.
PresentationAvailability
PresentationConnectionAvailableEvent
PresentationConnectionAvailableEvent
is fired on a
PresentationRequest
when a connection associated with the object is created.
PresentationConnection
PresentationConnectionCloseEvent
PresentationConnectionCloseEvent
is fired when a presentation connection enters a
closed
状态。
PresentationReceiver
PresentationConnectionList
PresentationConnectionList
represents the collection of non-terminated presentation connections. It is also a monitor for the event of new available presentation connection.
Example codes below highlight the usage of main features of the Presentation API:
controller.html
implements the controller and
presentation.html
implements the presentation. Both pages are served from the domain
http://example.org
(
http://example.org/controller.html
and
http://example.org/presentation.html
). These examples assume that the controlling page is managing one presentation at a time. Please refer to the comments in the code examples for further details.
<!-- controller.html -->
<button id="presentBtn" style="display: none;">Present</button>
<script>
// The Present button is visible if at least one presentation display is available
var presentBtn = document.getElementById("presentBtn");
// It is also possible to use relative presentation URL e.g. "presentation.html"
var presUrls = ["http://example.com/presentation.html",
"http://example.net/alternate.html"];
// show or hide present button depending on display availability
var handleAvailabilityChange = function(available) {
presentBtn.style.display = available ? "inline" : "none";
};
// Promise is resolved as soon as the presentation display availability is
// known.
var request = new PresentationRequest(presUrls);
request.getAvailability().then(function(availability) {
// availability.value may be kept up-to-date by the controlling UA as long
// as the availability object is alive. It is advised for the web developers
// to discard the object as soon as it's not needed.
handleAvailabilityChange(availability.value);
availability.onchange = function() { handleAvailabilityChange(this.value); };
}).catch(function() {
// Availability monitoring is not supported by the platform, so discovery of
// presentation displays will happen only after request.start() is called.
// Pretend the devices are available for simplicity; or, one could implement
// a third state for the button.
handleAvailabilityChange(true);
});
</script>
<!-- controller.html --> <script> presentBtn.onclick = function () { // Start new presentation. request.start() // The connection to the presentation will be passed to setConnection on // success. .then(setConnection); // Otherwise, the user canceled the selection dialog or no screens were // found. }; </script>
<!-- controller.html --> <button id="reconnectBtn" style="display: none;">Reconnect</button> <script> var reconnect = function () { // read presId from localStorage if exists var presId = localStorage["presId"]; // presId is mandatory when reconnecting to a presentation. if (!!presId) { request.reconnect(presId) // The new connection to the presentation will be passed to // setConnection on success. .then(setConnection); // No connection found for presUrl and presId, or an error occurred. } }; // On navigation of the controller, reconnect automatically. document.addEventListener("DOMContentLoaded", reconnect); // Or allow manual reconnection. reconnectBtn.onclick = reconnect; </script>
<!-- controller.html --> <!-- Setting presentation.defaultRequest allows the page to specify the PresentationRequest to use when the controlling UA initiates a presentation. --> <script> navigator.presentation.defaultRequest = new PresentationRequest(presUrls); navigator.presentation.defaultRequest.onconnectionavailable = function(evt) { setConnection(evt.connection); }; </script>
<!-- controller.html -->
<button id="disconnectBtn" style="display: none;">Disconnect</button>
<button id="stopBtn" style="display: none;">Stop</button>
<button id="reconnectBtn" style="display: none;">Reconnect</button>
<script>
let connection;
// The Disconnect and Stop buttons are visible if there is a connected presentation
const stopBtn = document.querySelector("#stopBtn");
const reconnectBtn = document.querySelector("#reconnectBtn");
const disconnectBtn = document.querySelector("#disconnectBtn");
stopBtn.onclick = _ => {
connection && connection.terminate();
};
disconnectBtn.onclick = _ => {
connection && connection.close();
};
function setConnection(newConnection) {
// Disconnect from existing presentation, if not attempting to reconnect
if (connection && connection != newConnection && connection.state != 'closed') {
connection.onclosed = undefined;
connection.close();
}
// Set the new connection and save the presentation ID
connection = newConnection;
localStorage["presId"] = connection.id;
function showConnectedUI() {
// Allow the user to disconnect from or terminate the presentation
stopBtn.style.display = "inline";
disconnectBtn.style.display = "inline";
reconnectBtn.style.display = "none";
}
function showDisconnectedUI() {
disconnectBtn.style.display = "none";
stopBtn.style.display = "none";
reconnectBtn.style.display = localStorage["presId"] ? "inline" : "none";
}
// Monitor the connection state
connection.onconnect = _ => {
showConnectedUI();
// Register message handler
connection.onmessage = message => {
console.log(`Received message: ${message.data}`);
};
// Send initial message to presentation page
connection.send("Say hello");
};
connection.onclose = _ => {
connection = null;
showDisconnectedUI();
};
connection.onterminate = _ => {
// Remove presId from localStorage if exists
delete localStorage["presId"];
connection = null;
showDisconnectedUI();
};
};
</script>
<!-- presentation.html --> <script> var addConnection = function(connection) { this.onmessage = function (message) { if (message.data == "say hello") this.send("hello"); }; }; navigator.presentation.receiver.connectionList.then(function (list) { list.connections.map(function (connection) { addConnection(connection); }); list.onconnectionavailable = function (evt) { addConnection(evt.connection); }; }); </script>
<!-- controller.html --> <script> connection.send("{string: '你好,世界!', lang: 'zh-CN'}"); connection.send("{string: 'こんにちは、世界!', lang: 'ja'}"); connection.send("{string: '안녕하세요, 세계!', lang: 'ko'}"); connection.send("{string: 'Hello, world!', lang: 'en-US'}"); </script> <!-- presentation.html --> <script> connection.onmessage = function (message) { var messageObj = JSON.parse(message.data); var spanElt = document.createElement("SPAN"); spanElt.lang = messageObj.lang; spanElt.textContent = messageObj.string; document.appendChild(spanElt); }; </script>
| 规范 | 状态 | 注释 |
|---|---|---|
| Presentation API | 候选推荐 | 初始定义。 |
Presentation
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Presentation
|
Chrome 48 | Edge ≤79 | Firefox 51 | IE 不支持 No | Opera Yes | Safari ? | WebView Android 不支持 No | Chrome Android 48 | Firefox Android 51 | Opera Android Yes | Safari iOS ? | Samsung Internet Android 5.0 |
defaultRequest
|
Chrome 48 | Edge ≤79 | Firefox 51 | IE 不支持 No | Opera Yes | Safari ? | WebView Android 不支持 No | Chrome Android 48 | Firefox Android 51 | Opera Android Yes | Safari iOS ? | Samsung Internet Android 5.0 |
receiver
|
Chrome 48 | Edge ≤79 | Firefox 51 | IE 不支持 No | Opera Yes | Safari ? | WebView Android 不支持 No | Chrome Android 48 | Firefox Android 51 | Opera Android Yes | Safari iOS ? | Samsung Internet Android 5.0 |
完整支持
不支持
兼容性未知
实验。期望将来行为有所改变。
用户必须明确启用此特征。
Presentation API polyfill contains a JavaScript polyfill of the Presentation API specification under standardisation within the Second Screen Working Group at W3C. The polyfill is mostly intended for exploring how the Presentation API may be implemented on top of different presentation mechanisms.