Capacités des médias et des appareils du navigateur

Indicateur d’état de connexion du pupitre audio à distance

Réalisez un indicateur d’état réseau dans le contexte d’une console audio à distance : contenu réaliste, contrôles actionnables, retour d’état clair et mise en page adaptable à toutes les tailles.

Capacités des médias et des appareils du navigateurIndicateur d’état de connexionHTMLCSSBrowser API
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Indicateur d’état de connexion du pupitre audio à distance</title>
  <style>
    :root { --ink:#30231f; --paper:#f9efe5; --accent:#8b6fb0; --secondary:#d7a971; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:Avenir,"PingFang SC",sans-serif; background:var(--paper); }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1320px,calc(100% - 56px));margin:auto;padding:10vh 0}.mast{display:grid;grid-template-columns:minmax(0,1fr) 160px;gap:10vw;margin-block:6vh;align-items:start;margin-bottom:10vh}.mast h1{font-family:Avenir,"PingFang SC",sans-serif;font-weight:500;font-size:clamp(38px,8vw,88px);letter-spacing:-.055em;margin:0;line-height:.96}.eyebrow{display:block;margin-bottom:24px;font:600 10px/1 ui-monospace,monospace;letter-spacing:.22em}.intro{max-width:52ch;margin-top:28px;line-height:1.8}.scenario{font-size:13px;text-align:right}.demo{border-radius:1px;border-color:color-mix(in srgb,var(--ink) 35%,transparent);box-shadow:none;position:relative;min-height:420px;padding:clamp(28px,5vw,70px);background:transparent}@media(max-width:700px){.page{width:calc(100% - 24px);padding:36px 0}.mast{grid-template-columns:1fr;margin-bottom:30px}.scenario{text-align:left}.demo{padding:18px}}
    .panel{padding:30px;border:0;border-radius:42px 12px;background:color-mix(in srgb,var(--secondary) 18%,var(--paper))}.row{display:flex;flex-wrap:wrap;gap:14px;align-items:center}.stack{display:flex;flex-direction:column;gap:20px}.action{min-height:48px;padding:12px 22px;border:0;border-radius:50% 50% 18px 18px;background:color-mix(in srgb,var(--secondary) 42%,transparent);font-weight:800}.action.primary,.action.is-active{color:var(--paper);background:var(--accent)}.muted{color:color-mix(in srgb,var(--ink) 64%,transparent);line-height:1.7}.status{min-height:25px;margin-top:16px;color:var(--accent)}.metric{font-size:clamp(32px,7vw,66px);font-weight:800}.meter{height:11px;border-radius:50%;background:color-mix(in srgb,var(--ink) 10%,transparent)}.meter>i{display:block;height:100%;border-radius:inherit;background:var(--accent)}.chip{padding:8px 12px;border-radius:50%;background:var(--paper)}
    .composition-index{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px}.index-mark{display:grid;align-content:space-between;width:76px;padding:16px 10px;border:1px solid var(--line);color:var(--accent);background:color-mix(in srgb,var(--paper) 82%,transparent);text-align:center}.index-mark strong{font:900 34px/1 ui-monospace,monospace}.index-mark span{writing-mode:vertical-rl;font:800 10px/1.2 ui-monospace,monospace;letter-spacing:.18em}.composition-index .demo{grid-column:1;grid-row:1}.composition-index::before{content:"";position:absolute;left:-12px;top:38px;width:5px;height:45%;background:linear-gradient(var(--accent),var(--secondary))}@media(max-width:700px){.composition-index{grid-template-columns:1fr}.index-mark{grid-row:1;width:auto;grid-template-columns:auto 1fr}.index-mark span{writing-mode:horizontal-tb}.composition-index .demo{grid-row:2}}
    .network-console{display:grid;grid-template-columns:minmax(220px,.7fr) minmax(260px,1fr) minmax(180px,.6fr);gap:0;border:1px solid var(--line);background:var(--paper)}.network-console>header{display:grid;align-content:center;justify-items:start;gap:12px;padding:26px;color:var(--paper);background:#101827}.network-console h2{margin:.2em 0}.network-console header output{font-size:38px;font-weight:900}#networkLamp{width:22px;aspect-ratio:1;border-radius:50%;background:#8a8f98;box-shadow:0 0 0 8px #ffffff12}#networkLamp.is-online{background:#34d399;box-shadow:0 0 24px #34d399}.network-console>section{display:grid;align-content:center;gap:15px;padding:24px}.network-console dl{display:grid;gap:8px}.network-console dl div{display:flex;justify-content:space-between;gap:12px;padding-bottom:8px;border-bottom:1px dashed var(--line)}.network-console dd{margin:0;font-weight:900}.network-console>aside{padding:24px;border-left:1px solid var(--line)}#networkTimeline{display:grid;gap:8px;padding-left:20px;font-size:12px}@media(max-width:760px){.network-console{grid-template-columns:1fr}.network-console>aside{border-left:0;border-top:1px solid var(--line)}}.workflow-compare{display:grid;grid-template-columns:minmax(230px,.55fr) minmax(0,1.45fr);gap:18px}.compare-stage{display:grid;gap:12px;min-width:0}.compare-stage>header{display:flex;justify-content:space-between;gap:16px;align-items:end}.compare-stage h2{margin:.2em 0}.compare-core{--compare-split:50%;min-width:0;padding:14px;clip-path:inset(0 calc(100% - var(--compare-split)) 0 0);outline:1px dashed var(--accent);outline-offset:-8px;transition:clip-path .25s,filter .25s}.compare-core[data-compare-channel="B"]{filter:hue-rotate(32deg) saturate(1.15)}.compare-controls{display:grid;align-content:start;gap:16px;padding:20px;border:1px solid var(--line);border-radius:24px 4px 24px 4px;background:var(--paper)}.compare-controls fieldset,.compare-controls>label{display:grid;gap:8px}.compare-controls input[type="range"]{width:100%}#workflowCompareShelf{display:grid;gap:6px;padding:0;margin:0;list-style:none}#workflowCompareShelf li{display:grid;grid-template-columns:auto 1fr auto;gap:8px;padding:9px;border-top:1px solid var(--line);font-size:12px}@media(max-width:900px){.workflow-compare{grid-template-columns:1fr}.compare-stage{order:-1}.compare-core{clip-path:none;border-left:8px solid var(--accent)}}
  </style>
</head>
<body data-aesthetic="minimal" data-composition="field-index">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">minimal / indicateur d’état réseau / BEGINNER</span><h1>Indicateur d’état de connexion du pupitre audio à distance</h1><p class="intro">Réalisez un indicateur d’état réseau dans le contexte d’une console audio à distance : contenu réaliste, contrôles actionnables, retour d’état clair et mise en page adaptable à toutes les tailles.</p></div><span class="scenario">Console audio à distance</span></header>
    <div class="composition-index"><section class="demo" aria-label="Zone interactive d’indication de l’état de connexion de la télécommande audio"><div class="workflow-compare"><form id="workflowCompareControls" class="compare-controls"><fieldset><legend>Canal de comparaison</legend><label><input type="radio" name="workflowChannel" value="A" checked>A · vérification des autorisations de la console audio à distance</label><label><input type="radio" name="workflowChannel" value="B">B · Journal des capacités de la console audio à distance</label></fieldset><label>Poids des éléments de contrôle<input id="workflowCompareWeight" type="range" min="10" max="90" value="50"><output id="workflowCompareWeightValue">élément 50</output></label><label><input id="workflowCompareFreeze" type="checkbox">Geler la version actuelle</label><button id="workflowCompareCapture" class="action primary" type="button">Échantillonner et enregistrer les capacités</button><ol id="workflowCompareShelf" aria-label="Enregistrement de version"></ol></form><section class="compare-stage"><header><span class="eyebrow">Console audio de télécommande COMPARE</span><h2>Comparaison de deux versions de la console de télécommande audio</h2><output id="workflowCompareLive">Version A en attente d’échantillonnage</output></header><section id="workflowCore" class="workflow-core compare-core" data-compare-channel="A" style="--compare-split:50%"><!-- 11DZ_CORE_START:browser-media-device-network-state --><div class="network-console"><header><span class="eyebrow">NETWORK EVENTS</span><h2>État de connexion de la console de télécommande audio</h2><div id="networkLamp" aria-hidden="true"></div><output id="networkStatus">Détection en cours</output></header><section><dl><div><dt>Le navigateur détermine</dt><dd id="networkNative">—</dd></div><div><dt>Type de connexion</dt><dd id="networkType">Non public</dd></div><div><dt>Économiser des données</dt><dd id="networkSaveData">Non public</dd></div></dl><label><input id="networkDrill" type="checkbox" data-core-bridge="browser-media-device-network-state">Lancer la vue de simulation hors ligne</label><button id="networkCheckpoint" class="action primary" type="button">Point de contrôle de l’état de l’enregistrement</button></section><aside><h3>Chronologie de l’événement</h3><ol id="networkTimeline"><li>attendre les événements online / offline</li></ol></aside></div><!-- 11DZ_CORE_END --></section></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section><aside class="index-mark" aria-hidden="true"><strong>05</strong><span>Console audio à distance FIELD INDEX</span></aside></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:browser-media-device-network-state */
const networkEvents=[];const networkConnection=navigator.connection||navigator.mozConnection||navigator.webkitConnection;function networkSnapshot(source){const drilled=document.querySelector('#networkDrill').checked;const online=navigator.onLine&&!drilled;document.querySelector('#networkLamp').classList.toggle('is-online',online);document.querySelector('#networkStatus').textContent=online?'Connexion disponible':drilled?'Exercice hors ligne':'Connexion interrompue';document.querySelector('#networkNative').textContent=navigator.onLine?'online':'offline';document.querySelector('#networkType').textContent=networkConnection?.effectiveType||'Non publié dans le navigateur';document.querySelector('#networkSaveData').textContent=networkConnection?.saveData?'Activé':'Non activé ou inconnu';if(source){networkEvents.unshift({source,state:online?'En ligne':'Hors ligne',time:new Date()});networkEvents.splice(6);document.querySelector('#networkTimeline').replaceChildren(...networkEvents.map(entry=>{const item=document.createElement('li');item.textContent=entry.time.toLocaleTimeString()+' · '+entry.source+' · '+entry.state;return item;}));announce('État du réseau enregistré :'+(online?'En ligne':'Hors ligne'));}}addEventListener('online',()=>networkSnapshot('événement en ligne'));addEventListener('offline',()=>networkSnapshot('événement offline'));networkConnection?.addEventListener?.('change',()=>networkSnapshot('Modification des paramètres de connexion'));document.querySelector('#networkDrill').addEventListener('change',()=>networkSnapshot('commutateur d’exercice'));document.querySelector('#networkCheckpoint').addEventListener('click',()=>networkSnapshot('Point de contrôle manuel'));networkSnapshot();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"browser-media-device-network-state","selector":"[data-core-bridge=\"browser-media-device-network-state\"]","mode":"toggle","key":" "};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Version de base '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.setAttribute('aria-keyshortcuts',workflowBridgeSpec.key===' '?'Space':workflowBridgeSpec.key);const workflowBridgeToggleKeyMatches=event=>event.key===workflowBridgeSpec.key||event.key==='Spacebar'||event.code==='Space';workflowBridgeControl.addEventListener('keydown',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();});workflowBridgeControl.addEventListener('keyup',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();workflowBridgeControl.click();});workflowBridgeControl.addEventListener("change",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowCompareCore=document.querySelector('#workflowCore');const workflowCompareWeight=document.querySelector('#workflowCompareWeight');const workflowCompareState={channel:'A',weight:50,frozen:false,snapshots:[]};function workflowCompareFingerprint(){const controls=[...workflowCompareCore.querySelectorAll('input,select,textarea')];const outputs=[...workflowCompareCore.querySelectorAll('output,[role="status"],strong')].map(node=>node.textContent.trim()).filter(Boolean);return {controlValues:controls.map(control=>control.type==='checkbox'||control.type==='radio'?control.checked:control.value),summary:outputs.slice(0,4).join(' / '),nodes:workflowCompareCore.querySelectorAll('*').length};}function workflowCompareDrive(){workflowCompareCore.dataset.compareChannel=workflowCompareState.channel;workflowCompareCore.style.setProperty('--compare-split',workflowCompareState.weight+'%');document.querySelector('#workflowCompareWeightValue').textContent=workflowCompareState.weight+' élément';document.querySelector('#workflowCompareLive').textContent=workflowCompareState.channel+' Version · '+workflowCompareState.weight+' élément'+(workflowCompareState.frozen?' · figé':'');announce('La console de télécommande audio est en cours de consultation '+workflowCompareState.channel+' Version');}function workflowCompareCapture(source){const bridge=workflowBridgeActivate();const snapshot={...workflowCompareFingerprint(),channel:workflowCompareState.channel,weight:workflowCompareState.weight,source,bridge:bridge.summary};workflowCompareState.snapshots.push(snapshot);const item=document.createElement('li');item.innerHTML='<b>'+snapshot.channel+'</b><span>'+(snapshot.summary||snapshot.bridge)+'</span><small>'+snapshot.weight+' élément · '+snapshot.bridge+'</small>';document.querySelector('#workflowCompareShelf').prepend(item);announce('échantillonné '+snapshot.channel+' Version et enregistrement des capacités · '+bridge.summary);}document.querySelectorAll('[name="workflowChannel"]').forEach(input=>input.addEventListener('change',()=>{workflowCompareState.channel=input.value;workflowCompareDrive();}));workflowCompareWeight.addEventListener('input',()=>{workflowCompareState.weight=Number(workflowCompareWeight.value);workflowCompareDrive();});document.querySelector('#workflowCompareFreeze').addEventListener('change',event=>{workflowCompareState.frozen=event.currentTarget.checked;workflowCompareDrive();});document.querySelector('#workflowCompareCapture').addEventListener('click',()=>workflowCompareCapture('Échantillonnage du bouton'));workflowCompareCore.addEventListener('dblclick',()=>workflowCompareCapture('Double-clic sur la vue principale'));workflowCompareDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires