IlmHamroh
JavaScript Full-stack/13-qism. Brauzer API'lari, performans va xavfsizlik8/32-dars19 daqiqa
Mundarija (38)

JavaScript navigator va qurilma API'lari: tarmoq, til, to'liq ekran va ekran qulfi

Qisqacha: navigator — brauzer va qurilma haqidagi obyekt. navigator.onLine va online/offline hodisalari — tarmoq holati; navigator.language — foydalanuvchi tili; element.requestFullscreen() — to'liq ekran; navigator.wakeLock.request("screen") — ekran o'chib qolmasin; navigator.vibrate(200) — telefon tebranadi. Bu imkoniyatlar hamma joyda yo'q — shuning uchun "wakeLock" in navigator kabi imkoniyatni tekshirasiz, userAgent dan brauzer nomini o'qimaysiz.

Bu darsda

  • navigator.onLine va online/offline hodisalari bilan tarmoq holatini ko'rsatasiz va uning chegarasini bilasiz.
  • navigator.language va languages ni o'qib, ularni to'g'ri ishlatasiz.
  • Fullscreen API bilan elementni to'liq ekranga chiqarasiz va qaytarasiz.
  • Screen Wake Lock bilan ekranni yoniq ushlab turasiz va Vibration API'ni bilasiz.
  • userAgent o'rniga feature detection (imkoniyatni aniqlash) bilan yozasiz.

Oldin bilishingiz kerak: Permissions, Notifications va Geolocation, Sahifa hayot sikli va Page Visibility, Intl.NumberFormat, JS versiyalari va brauzer mosligi.

1. Nega bu kerak?

So'nggi ikki darsda navigator ning uch qismini ishlatdik: navigator.clipboard, navigator.share, navigator.geolocation. navigator — brauzerning "pasporti": u qanday brauzer, qaysi tilda, tarmoqqa ulanganmi va qurilma nimalarga qodir. Bugun undagi qolgan foydali narsalarni yig'amiz.

«Bahor» oshxonasida planshet turibdi — oshpaz retseptlarni shu yerdan o'qiydi. Uchta muammo bor:

  • Qo'li xamir, ekranga tegolmaydi — planshet 30 soniyada uxlab qoladi. Kerakli API — Screen Wake Lock.
  • Retsept rasmi kichik — to'liq ekranda ko'rsatish kerak. Fullscreen API.
  • Oshxonada Wi-Fi tez-tez uziladi — sahifa "Internet yo'q" deb ogohlantirsin. navigator.onLine va online/offline.

Mehmonlar uchun esa yana ikki savol: sayt qaysi tilda ochilsin (navigator.language) va telefon bron tasdiqlanganda tebransinmi (navigator.vibrate). Va eng muhimi — bularning hammasi har brauzerda bormi? Buni qanday bilish kerak?

2. Tarmoq holati: onLine, online, offline

2.1 Bayroq va hodisalar

js
console.log(navigator.onLine); // true yoki false

addEventListener("offline", () => console.log("Aloqa uzildi"));
addEventListener("online", () => console.log("Aloqa tiklandi"));

navigator.onLine — brauzerning "tarmoqqa ulanganmanmi?" degan bayrog'i. offline va online hodisalari window da keladi — holat o'zgarganda.

Vazifalar ilovasi loyihasi da buni ishlatgan edik va bitta nozik joyni aytgan edik: false ga ishonish mumkin, true ga — yo'q. true faqat "Wi-Fi yoki kabel ulangan" degani. Wi-Fi ulangan, lekin router internetga chiqmasa — bayroq baribir true. Shuning uchun vazifalar tarmoq xatosini fetch ning catch ida ham tekshiradi.

2.2 Jonli misol

html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
  #net { padding: 0.5rem 0.75rem; border-radius: 0.5rem;
    background: #e8f1ec; color: #1f6f4a; }
  #net.off { background: #fde8e7; color: #b3261e; }
</style>
<p id="net" role="status">…</p>
<script>
  const net = document.getElementById("net");

  function showNetwork() {
    const online = navigator.onLine;
    net.textContent = online
      ? "Internet bor"
      : "Internet yo'q — o'zgarishlar keyin yuboriladi";
    net.classList.toggle("off", !online);
  }

  addEventListener("online", () => {
    showNetwork();
    console.log("online");
  });
  addEventListener("offline", () => {
    showNetwork();
    console.log("offline");
  });
  showNetwork(); // boshlang'ich holat
</script>

Sinash: DevTools → Network paneli → No throttling ro'yxatidan Offline ni tanlang. Yashil yozuv qizilga o'zgaradi va konsolda offline. Yana No throttling — online. Biz Chrome 154 da tarmoqni o'chirib-yoqib tekshirdik: ikkala hodisa shu jonli oynaning ichida ham keldi, navigator.onLine mos ravishda false va true bo'ldi.

Naqsh tanish: matchMedia darsidagidek — boshlang'ich holatni qo'lda chizamiz (showNetwork()), keyin o'zgarishlarni tinglaymiz.

2.3 Ulanish sifati: navigator.connection

Chrome'da navigator.connection ham bor — Network Information API: effectiveType ("4g", "3g", "2g", "slow-2g"), downlink (taxminiy tezlik, Mbit/s), saveData (foydalanuvchi "trafikni tejash" rejimini yoqqanmi). Sekin tarmoqda katta video o'rniga rasm berish uchun qulay.

Lekin u Baseline emas: Firefox va Safari'da yo'q, web-features ma'lumotiga ko'ra to'liq qo'llanishi faqat Android Chrome'da (2026-oktabr). Faqat qo'shimcha qulaylik sifatida ishlating — u bo'lmasa ham sahifa ishlasin:

js
const saveData = navigator.connection?.saveData === true;

Tekshirib ko'ring: Telefon Wi-Fi'ga ulangan, lekin router internetga chiqmaydi. navigator.onLine nima qaytaradi? Saytingiz "Internet yo'q" deb to'g'ri ko'rsatishi uchun yana nima kerak?

Javob

true — tarmoq adapteri ulangan. Bayroq internet ishlashini tekshirmaydi. Haqiqiy holatni so'rov natijasidan bilasiz: fetch yiqilsa (catch), "aloqa yo'q" deb ko'rsating. false esa ishonchli — tarmoq umuman yo'q.

3. Til: navigator.language va languages

3.1 Ikki xususiyat

js
console.log(navigator.language); // masalan "uz-UZ"
console.log(navigator.languages); // masalan ["uz-UZ", "ru", "en"]
  • navigator.language — brauzer interfeysining asosiy tili.
  • navigator.languages — foydalanuvchi afzal ko'rgan tillar ro'yxati, tartib bilan: birinchisi — eng ma'quli. Chrome'da: Sozlamalar → Tillar.

Qiymatlar — til teglari: uz (o'zbek), uz-UZ (O'zbekistondagi o'zbek), ru-RU, en-US. Bu Intl.NumberFormat darsidagi lokal satrlarining o'zi. Brauzer xuddi shu ro'yxatni har so'rov bilan serverga ham yuboradi — Accept-Language sarlavhasida.

3.2 Qanday ishlatish kerak

Til foydalanuvchiga taklif qilish uchun, majburlash uchun emas. Avval brauzeringiz nima deyishini ko'ring:

html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
  dt { font-weight: 700; }
</style>
<dl>
  <dt>navigator.language</dt><dd id="lang"></dd>
  <dt>navigator.languages</dt><dd id="langs"></dd>
  <dt>Osh narxi (brauzer tilida)</dt><dd id="price"></dd>
  <dt>Osh narxi (sahifa tilida)</dt><dd id="price-uz"></dd>
</dl>
<script>
  const price = 35000;
  const groups = new Intl.NumberFormat("uz");

  // 12-qismdagi somYoz: Chrome'da "uz" son qoidalari yo'q
  function somYoz(n) {
    const text = groups
      .formatToParts(n)
      .map((p) => (p.type === "group" ? "\u00a0" : p.value))
      .join("");
    return text + " so'm";
  }

  const browserPrice = new Intl.NumberFormat(navigator.language)
    .format(price);
  document.getElementById("lang").textContent = navigator.language;
  document.getElementById("langs").textContent =
    navigator.languages.join(", ");
  document.getElementById("price").textContent =
    browserPrice + " so'm";
  document.getElementById("price-uz").textContent = somYoz(price);
</script>

Bu oynada nima ko'rinishi — sizning brauzeringizga bog'liq. Bizning sinov Chrome'imiz en-GB edi: languages — en-GB, en-US, en, brauzer tilidagi narx — 35,000 so'm (vergul bilan), sahifa tilidagisi — 35 000 so'm. Nemischa brauzerda birinchisi 35.000 bo'lardi. O'zbek tilidagi sahifada inglizcha vergul yoki nemischa nuqta g'alati turadi. Shuning uchun narxni sahifa tilida formatlang, brauzer tilida emas. somYoz — Intl.NumberFormat darsidagi funksiya: Chrome'da uz son qoidalari yo'qligi uchun ajratuvchini o'zimiz qo'yamiz.

navigator.language — "bu sayt boshqa tilda ham bor" taklifi uchun:

js
const wantsRussian = navigator.languages.some((lang) =>
  lang.startsWith("ru"),
);
if (wantsRussian) {
  showLanguageOffer("ru"); // faqat taklif, yo'naltirish emas
}

Avtomatik yo'naltirmang: mehmon Dilshod akaning brauzeri ruscha bo'lishi mumkin, lekin u o'zbekcha o'qimoqchi. Taklif — bir bosishda yopiladigan banner.

languagechange hodisasi ham bor — foydalanuvchi sozlamalarda tilni almashtirsa, window da keladi. Kam ishlatiladi.

4. To'liq ekran: Fullscreen API

4.1 Ochish va yopish

Video pleyerdagi tugmasini eslang. Istalgan element shunday qila oladi:

js
await photo.requestFullscreen(); // element butun ekranni egallaydi
await document.exitFullscreen(); // oddiy holatga qaytish
console.log(document.fullscreenElement); // element yoki null
  • element.requestFullscreen() — elementning metodi, Promise qaytaradi.
  • document.exitFullscreen() — hujjatning metodi: to'liq ekrandan chiqish.
  • document.fullscreenElement — hozir to'liq ekrandagi element, yo'q bo'lsa null.
  • fullscreenchange hodisasi — kirganda ham, chiqqanda ham keladi. Foydalanuvchi Esc bilan chiqsa ham.

4.2 Faqat bosishda

Sahifa ochilishi bilan requestFullscreen() chaqirsak, Chrome 154 rad etdi:

text
TypeError: Permissions check failed

Konsolda yana ogohlantirish: Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture. — "bu API faqat foydalanuvchi harakati bilan ishga tushadi". Sabab tushunarli: aks holda reklama sahifasi butun ekranni o'zi egallab olardi. fullscreenerror hodisasi ham keldi.

4.3 «Bahor»: retsept rasmi

html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
  #photo { position: relative; height: 140px; border-radius: 0.5rem;
    background: linear-gradient(135deg, #e8a33d, #c0392b);
    display: grid; place-items: center; color: #fff; }
  #photo:fullscreen { border-radius: 0; font-size: 2rem; }
  button { font: inherit; padding: 0.4rem 0.8rem; }
  #toggle { position: absolute; top: 0.5rem; right: 0.5rem; }
</style>
<div id="photo">
  Osh: tayyorlash bosqichlari
  <button id="toggle" type="button">To'liq ekran</button>
</div>
<script>
  const photo = document.getElementById("photo");
  const toggle = document.getElementById("toggle");

  toggle.addEventListener("click", async () => {
    if (document.fullscreenElement) {
      await document.exitFullscreen();
    } else {
      await photo.requestFullscreen();
    }
  });

  document.addEventListener("fullscreenchange", () => {
    const isFull = document.fullscreenElement === photo;
    toggle.textContent = isFull ? "Chiqish" : "To'liq ekran";
    console.log(isFull ? "to'liq ekran" : "oddiy");
  });
</script>

«To'liq ekran» ni bosing — rasm butun ekranni egallaydi, tugma Chiqish ga aylanadi, konsolda to'liq ekran. Chiqish yoki Esc — oddiy. Biz ikkala bosishni sinadik: to'liq ekran, keyin oddiy.

Uch narsaga qarang:

  • Tugma elementning ichida. To'liq ekranda faqat shu element va uning ichidagilar ko'rinadi. Tugma tashqarida bo'lsa — to'liq ekranda u ko'rinmaydi va foydalanuvchida faqat Esc qoladi.
  • :fullscreen CSS psevdo-klassi — to'liq ekrandagi element uchun alohida stil. Orqa fon esa ::backdrop bilan bo'yaladi, xuddi modal oynadagidek.
  • Tugma matni fullscreenchange da yangilanadi, bosishda emas. Esc bilan chiqilganda bosish bo'lmaydi — hodisa esa keladi.

Bu jonli oyna to'liq ekranga ruxsat berilgan: sayt unga allow="fullscreen" qo'ygan. Iframe ichida to'liq ekran faqat ota sahifa shunday ruxsat bersa ishlaydi — YouTube'ni saytingizga joylashtirganda ham allowfullscreen shuning uchun kerak.

Diqqat: iPhone'dagi Safari elementni to'liq ekranga chiqarmaydi — faqat <video> ni (web-features, 2026-oktabr: Fullscreen API iOS Safari'da yo'q). requestFullscreen bor-yo'qligini tekshiring va tugmani faqat u bor bo'lsa ko'rsating.

Tekshirib ko'ring: Sardor tugma matnini click tinglovchisida o'zgartirdi: "To'liq ekran" → "Chiqish". Foydalanuvchi Esc bilan chiqdi. Tugmada nima yozilgan bo'ladi?

Javob

Chiqish — noto'g'ri. Esc tugma bosilishi emas, click kelmadi va matn yangilanmadi. To'g'risi — matnni fullscreenchange hodisasida document.fullscreenElement ga qarab yozish: u har qanday kirish va chiqishda keladi.

5. Ekran o'chmasin: Screen Wake Lock

5.1 So'rash va qo'yib yuborish

Telefon bir muddat tegilmasa, ekranni o'chiradi — batareya tejaladi. Lekin retsept o'qiyotgan oshpaz yoki chiptadagi QR-kodni ko'rsatayotgan mehmon uchun bu xalaqit. Screen Wake Lock API — "ekran qulfi": sahifa ochiq va ko'rinib turganda ekran o'chmaydi.

js
const lock = await navigator.wakeLock.request("screen");
console.log(lock.released); // false — qulf ushlab turilibdi

lock.addEventListener("release", () => {
  console.log("Ekran qulfi qo'yib yuborildi");
});

await lock.release(); // o'zimiz qo'yib yuboramiz

request("screen") — WakeLockSentinel ("qorovul") obyektini qaytaradi. Uning released xususiyati, release() metodi va release hodisasi bor. Live Server'da sinadik: tugma bosilganda request muvaffaqiyatli bo'ldi, type — "screen", released — false.

5.2 Tab yashirinsa — qulf yo'qoladi

Muhim qoida: foydalanuvchi boshqa tabga yoki ilovaga o'tsa, brauzer qulfni o'zi qo'yib yuboradi. Qaytganda u avtomatik tiklanmaydi. Qulfning butun "hayoti" — sxemada. «visible → kod qayta so'radi» strelkasiga qarang: tab qaytganda qulfni kod qayta so'raydi, brauzer emas:

stateDiagram-v2
  state "Qulf yo'q" as Yoq
  state "Qulf ushlangan" as Ushlangan
  [*] --> Yoq: sahifa ochildi
  Yoq --> Ushlangan: request("screen")
  Ushlangan --> Yoq: release()
  Ushlangan --> Yoq: tab yashirindi
  Yoq --> Ushlangan: visible → kod qayta so'radi

Shuning uchun Page Visibility darsidagi visibilitychange hodisasida qayta so'raymiz:

js
let lock = null;

async function keepScreenOn() {
  try {
    lock = await navigator.wakeLock.request("screen");
  } catch (error) {
    console.log(`Ekran qulfi yo'q: ${error.name}`);
  }
}

document.addEventListener("visibilitychange", () => {
  const wanted = lock !== null; // foydalanuvchi yoqqan edi
  if (wanted && document.visibilityState === "visible") {
    keepScreenOn();
  }
});

5.3 Qachon rad etiladi

  • Batareya kam yoki quvvat tejash rejimi — brauzer NotAllowedError bilan rad etishi mumkin.
  • Ruxsatlar siyosati. Bu darsdagi jonli oynalarda ekran qulfi yopiq. Chrome 154 da sinadik: NotAllowedError: Failed to execute 'request' on 'WakeLock': Access to Screen Wake Lock features is disallowed by permissions policy. Sinash — Live Server'da.
  • Xavfsiz kontekst — HTTP'da navigator.wakeLock yo'q.

Screen Wake Lock 2025-yil martidan barcha asosiy brauzerlarda bor (Baseline, web-features). Eski brauzerlar uchun "wakeLock" in navigator tekshiruvi.

6. Tebranish: Vibration API

js
navigator.vibrate(200); // 200 ms tebranish
navigator.vibrate([100, 50, 100]); // tebran, to'xta, tebran
navigator.vibrate(0); // to'xtatish

Massiv — "naqsh": toq o'rinlarda tebranish, juft o'rinlarda tanaffus (ms). Metod true yoki false qaytaradi — so'rov qabul qilindimi.

Cheklovlar ko'p:

  • Faqat Android brauzerlarida haqiqatan tebranadi. Safari (iPhone ham) va Firefox'da yo'q (web-features, 2026-oktabr). Kompyuterda Chrome true qaytaradi, lekin tebranadigan narsa yo'q.
  • Foydalanuvchi sahifaga kamida bir marta tegishi kerak. Sahifa ochilishi bilan chaqirsak, Chrome false qaytardi va konsolga yozdi: Blocked call to navigator.vibrate because user hasn't tapped on the frame or any embedded frame yet — "foydalanuvchi hali sahifaga tegmagan". Bosishdan keyin — true.

Tebranish — qo'shimcha signal. Uni yagona signal qilmang: Malika va Bobur uchun ham, iPhone egalari uchun ham ekranda xabar bo'lsin. Va kam ishlating — har bosishda tebranadigan sayt asabga tegadi.

7. userAgent emas — imkoniyatni tekshiring

7.1 userAgent nima deydi

navigator.userAgent — brauzer o'zini tanishtiradigan satr. Chrome 154 da (Windows 11) shunday:

text
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36

Undagi "yolg'on"larni sanang: Chrome o'zini Mozilla (1990-yillar brauzeri), AppleWebKit va Safari deb ham ataydi. Windows 11 da Windows NT 10.0 deydi. Versiya 154.0.0.0 — oxirgi raqamlar ataylab nol. Bu User-Agent qisqartirish (UA reduction): Chrome 2022–2023 yillarda satrni "muzlatdi". Sababi — barmoq izi olish (fingerprinting): sayt brauzerning mayda belgilarini (aniq versiya, OS, ekran, shriftlar) yig'ib, cookie'siz ham sizni boshqa saytlarda tanib oladi. Xuddi barmoq izi kabi — har kishiniki deyarli noyob. Satrdagi ma'lumot qancha kam bo'lsa, iz shuncha xira. Biz satrni sinov uchun ishlatilgan headless (oynasiz) Chrome'dan oldik — u yerda Chrome o'rnida HeadlessChrome yozilgan, qolgani bir xil.

Tarixan saytlar userAgent dan "agar Chrome bo'lsa…" deb qaror qilgan. Natijada har yangi brauzer o'zini boshqasi deb ko'rsatishga majbur bo'lgan. Hammasi shuning uchun aralash.

7.2 Chromium'ning yangi yo'li: userAgentData

Chromium brauzerlarida (Chrome, Edge, Opera) User-Agent Client Hints bor. Bu — userAgent satrining o'rnini bosuvchi yangi usul: brauzer o'zi haqida hamma narsani bitta satrda aytmaydi, sayt kerakli bo'lagini alohida so'raydi. JavaScript'da u navigator.userAgentData obyekti:

js
console.log(navigator.userAgentData.mobile); // false
console.log(navigator.userAgentData.platform); // "Windows"

Batafsil ma'lumot (platformVersion, aniq versiya) — faqat so'ralsa, Promise orqali: getHighEntropyValues(["platformVersion"]). Chrome 154 da u "19.0.0" qaytardi — Windows 11 shunday aniqlanadi (13 va undan katta). Lekin Firefox va Safari'da userAgentData umuman yo'q (web-features: faqat Chromium). Shuning uchun u ham "brauzer qaysi?" savoliga universal javob emas.

7.3 Feature detection

JS versiyalari va brauzer mosligi darsida tamoyilni o'rgandik: brauzer nomini emas, imkoniyatni so'rang. Bugungi API'lar uchun:

html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
  td { padding: 0.15rem 0.6rem; }
</style>
<table id="features"><tbody></tbody></table>
<script>
  const checks = {
    "Clipboard (yozish)": "clipboard" in navigator,
    "Web Share": "share" in navigator,
    "Geolocation": "geolocation" in navigator,
    "Notifications": "Notification" in window,
    "Screen Wake Lock": "wakeLock" in navigator,
    "Vibration": "vibrate" in navigator,
    "Fullscreen": "requestFullscreen" in document.documentElement,
    "userAgentData": "userAgentData" in navigator,
  };
  const body = document.querySelector("#features tbody");
  for (const [name, has] of Object.entries(checks)) {
    const row = body.insertRow();
    row.insertCell().textContent = name;
    row.insertCell().textContent = has ? "✅ bor" : "❌ yo'q";
  }
</script>

Kompyuterdagi Chrome'da hammasi ✅. iPhone'dagi Safari'da oching — Vibration, userAgentData va Fullscreen ❌ bo'ladi. Bu jadval API borligini ko'rsatadi, ruxsat berilganini emas: bu oynada Geolocation ✅, lekin o'tgan darsda ko'rganimizdek, ruxsatlar siyosati uni yopgan.

Qoida — progressiv yaxshilash (progressive enhancement): asosiy ish hamma joyda ishlaydi, qo'shimcha qulaylik faqat imkoniyat bor joyda qo'shiladi.

js
if ("wakeLock" in navigator) {
  keepOnButton.hidden = false; // tugma faqat ishlaydigan joyda
}

Imkoniyat yo'q bo'lsa — tugma ko'rinmaydi, xato chiqmaydi, sayt baribir ishlaydi.

Tekshirib ko'ring: Sardor yozdi: if (navigator.userAgent.includes("Android")) navigator.vibrate(200);. Ikki muammoni toping.

Javob
  1. Android'dagi Firefox ham "Android" yozadi, lekin vibrate u yerda yo'q — chaqiruv xato beradi (navigator.vibrate is not a function). 2) Kelajakda tebranish boshqa qurilmalarda paydo bo'lsa, kod uni bilmaydi. To'g'risi: if ("vibrate" in navigator) navigator.vibrate(200); — aniq shu imkoniyatni tekshirish.

8. Boshqa foydali xususiyatlar

Xususiyat Nima beradi Qayerda
navigator.hardwareConcurrency protsessor yadrolari soni hamma brauzerda
navigator.maxTouchPoints bir vaqtda nechta barmoq (0 — sensorsiz) hamma brauzerda
navigator.deviceMemory taxminiy xotira, GB (0.25…8) faqat Chromium
navigator.cookieEnabled cookie yoqilganmi hamma brauzerda

hardwareConcurrency — Web Workers darsida kerak bo'ladi: nechta parallel ishchi yaratishni shu son bilan tanlash mumkin. deviceMemory ataylab yaxlitlanadi (8 dan katta bo'lsa ham 8) — yana o'sha fingerprinting'dan himoya.

9. Node'dagi navigator

Node 21 dan boshlab Node'da ham global navigator bor — lekin juda kichik:

js
console.log(typeof navigator); // object
console.log(navigator.userAgent); // Node.js/24
console.log(navigator.onLine); // undefined
console.log(navigator.clipboard); // undefined

Node 24 da userAgent, language, platform, hardwareConcurrency bor — server kodida yadrolar sonini bilish uchun qulay. onLine, clipboard, geolocation kabi qurilma API'lari esa yo'q: serverda ekran ham, foydalanuvchi ham yo'q. Bu yerda ham feature detection ishlaydi: "clipboard" in navigator — Node'da false.

10. Ko'p uchraydigan xatolar

10.1 navigator.onLine ga to'liq ishonish

true — internet bor degani emas. Tuzatish: haqiqiy holat — so'rov natijasi; onLine faqat "aniq yo'q" holati uchun.

10.2 Bosishsiz to'liq ekran yoki tebranish

Sahifa ochilishi bilan requestFullscreen() — TypeError: Permissions check failed; vibrate() — false. Tuzatish: foydalanuvchi harakatida chaqiring.

10.3 Ekran qulfini qayta so'ramaslik

Foydalanuvchi bir daqiqa Telegram'ga o'tib qaytdi — qulf yo'q, ekran yana o'chadi. Tuzatish: visibilitychange da "visible" bo'lganda qayta request.

10.4 Brauzer tiliga qarab yo'naltirish

Ruscha brauzerli mehmon o'zbekcha sahifani ochdi — sayt uni majburan ruscha versiyaga otdi. Tuzatish: til — taklif (banner), tanlov — foydalanuvchida; tanlovni eslab qoling.

10.5 userAgent bo'yicha qaror

"Safari bo'lsa — eski kod" — Safari yangilanadi, kod esa eskicha qoladi. Tuzatish: in operatori, typeof, CSS.supports() bilan imkoniyatni tekshiring.

11. Mashqlar

1-mashq (oson): Oflayn lenta

Sahifa tepasida faqat oflayn paytda ko'rinadigan qizil lenta bo'lsin: Internet yo'q. Onlayn bo'lganda — yashirin (hidden). Holat o'zgarganda konsolga lenta: ko'rinadi yoki lenta: yashirin chiqsin.

Yechim
html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 0; }
  #banner { background: #b3261e; color: #fff; padding: 0.5rem 1rem; }
  main { padding: 1rem; }
</style>
<div id="banner" role="status" hidden>Internet yo'q</div>
<main>«Bahor» menyusi</main>
<script>
  const banner = document.getElementById("banner");

  function updateBanner() {
    banner.hidden = navigator.onLine;
  }

  for (const type of ["online", "offline"]) {
    addEventListener(type, () => {
      updateBanner();
      const state = banner.hidden ? "yashirin" : "ko'rinadi";
      console.log(`lenta: ${state}`);
    });
  }
  updateBanner();
</script>

DevTools → Network → Offline: lenta chiqadi, konsolda lenta: ko'rinadi. Qaytaring — lenta: yashirin. Biz tarmoqni o'chirib-yoqib tekshirdik. banner.hidden = navigator.onLine — onlayn bo'lsa yashirin, bitta qatorda.

2-mashq (o'rta): To'liq ekran — faqat imkoniyat bo'lsa

«Bahor» menyusidagi taom rasmi uchun to'liq ekran tugmasini yozing. Tugma boshida hidden; JavaScript requestFullscreen borligini tekshirib, bor bo'lsagina ko'rsatsin. To'liq ekranda rasm ostida Esc — chiqish yozuvi ko'rinsin (CSS :fullscreen bilan). Konsolga holat o'zgarishi chiqsin: kirdi / chiqdi.

Yechim
html
<style>
  body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
  figure { margin: 0; }
  .dish { height: 120px; border-radius: 0.5rem;
    background: linear-gradient(135deg, #7fd1a5, #1f6f4a); }
  .hint { display: none; text-align: center; color: #fff; }
  figure:fullscreen { background: #000; display: grid;
    align-content: center; }
  figure:fullscreen .hint { display: block; }
</style>
<figure id="dish">
  <div class="dish"></div>
  <p class="hint">Esc — chiqish</p>
</figure>
<button id="full" type="button" hidden>To'liq ekranda ko'rish</button>
<script>
  const dish = document.getElementById("dish");
  const full = document.getElementById("full");

  if ("requestFullscreen" in dish) {
    full.hidden = false;
    full.addEventListener("click", () => dish.requestFullscreen());
  }

  document.addEventListener("fullscreenchange", () => {
    console.log(document.fullscreenElement ? "kirdi" : "chiqdi");
  });
</script>

Tugmani bosing — konsolda kirdi, Esc — chiqdi. Bosishni sinadik (kirdi, document.fullscreenElement — figure). Tugma figure dan tashqarida: to'liq ekranda u ko'rinmaydi — shuning uchun Esc — chiqish yozuvi kerak.

3-mashq (qiyin): Retsept rejimi

Live Server'da «Retsept rejimi» o'chirgichini yozing (<input type="checkbox" role="switch">). Yoqilganda ekran qulfi so'raladi, o'chirilganda qo'yib yuboriladi. Tab yashirinib qaytganda, o'chirgich yoqiq bo'lsa — qulf qayta so'raladi. Holat role="status" li maydonda: Ekran o'chmaydi, Ekran odatdagidek, xato bo'lsa — Ekran qulfi ishlamadi: <xato nomi>. wakeLock umuman yo'q bo'lsa — o'chirgich ko'rinmasin.

Yechim
html
<label hidden id="recipe-label">
  <input type="checkbox" role="switch" id="recipe"> Retsept rejimi
</label>
<p id="lock-status" role="status"></p>
<script>
  const recipe = document.getElementById("recipe");
  const statusText = document.getElementById("lock-status");
  let lock = null;

  async function acquire() {
    try {
      lock = await navigator.wakeLock.request("screen");
      statusText.textContent = "Ekran o'chmaydi";
      lock.addEventListener("release", () => {
        if (!recipe.checked) {
          statusText.textContent = "Ekran odatdagidek";
        }
      });
    } catch (error) {
      recipe.checked = false;
      statusText.textContent = `Ekran qulfi ishlamadi: ${error.name}`;
    }
  }

  if ("wakeLock" in navigator) {
    document.getElementById("recipe-label").hidden = false;
    recipe.addEventListener("change", async () => {
      if (recipe.checked) await acquire();
      else await lock?.release();
    });
    document.addEventListener("visibilitychange", () => {
      if (recipe.checked && document.visibilityState === "visible") {
        acquire();
      }
    });
  }
</script>

Live Server'da sinadik: o'chirgichni yoqish — Ekran o'chmaydi, o'chirish — release hodisasi va Ekran odatdagidek. release hodisasi tab yashiringanda ham keladi, lekin o'chirgich yoqiq qolgani uchun yozuv o'zgarmaydi — qaytganda visibilitychange qulfni tiklaydi. Bu jonli dars oynasida emas, aynan Live Server'da sinang: bu yerda ekran qulfi siyosat bo'yicha yopiq (NotAllowedError).

4-mashq: Amaliy tajriba — vazifalar va tarmoq

Kanon kodga tegmasdan tajriba: kurs/mashqlar/13/08-tarmoq-jurnali.js — Live Server'da ochilgan vazifalar sahifasining DevTools konsoliga qo'yiladigan kod. U online va offline hodisalarida bitta qator yozsin: vaqt (toLocaleTimeString("uz")), hodisa nomi, navigator.onLine va kanon ilovaning #aloqa yozuvidagi matn. Keyin DevTools Network panelida Offline'ni yoqing, vazifa qo'shing, Online'ni qaytaring. Jurnal va #aloqa matni bo'yicha savolga javob bering: oflayn paytda qo'shilgan vazifa qachon serverga ketdi?

Yechim
js
function logNetwork(event) {
  // #aloqa ni ilova o'zi yangilaydi — bir lahzadan keyin o'qiymiz
  setTimeout(() => {
    const time = new Date().toLocaleTimeString("uz");
    const text = document.getElementById("aloqa")?.textContent;
    const head = `${time} ${event.type} onLine=${navigator.onLine}`;
    console.log(`${head} aloqa="${text}"`);
  }, 100);
}

addEventListener("online", logNetwork);
addEventListener("offline", logNetwork);

offline da #aloqa oflayn holatni ko'rsatadi — kanon asosiy.js shu hodisada tarmoq holatini "oflayn" qiladi va kutayotgan so'rovni to'xtatadi. Oflayn paytda qo'shilgan vazifa ekranda va localStorage da darhol paydo bo'ladi. online kelganda kanon sinxronla() ni chaqiradi — o'shanda ro'yxat serverga ketadi. Jurnaldagi onLine=true dan keyingi aloqa matnini kuzating. setTimeout — bizning tinglovchimiz ilovanikidan oldin ham ishlashi mumkin, shuning uchun #aloqa ni bir lahza keyin o'qiymiz.

bash
git add 13/08-tarmoq-jurnali.js
git commit -m "13/08: vazifalar uchun online/offline jurnali"

12. Real ishda

  • Oflayn holat — Google Docs, Notion, Telegram Web "Ulanish kutilmoqda…" yozuvi. Ilovalar offline hodisasiga qo'shimcha ravishda serverga muntazam "tirikmisan?" so'rovi yuboradi.
  • To'liq ekran — video pleyerlar, onlayn taqdimotlar, rasm galereyalari, brauzer o'yinlari.
  • Ekran qulfi — retsept saytlari, navigatsiya, chipta va QR-kod sahifalari, taqdimot rejimi.
  • Feature detection — har qanday katta frontend loyihada. Modernizr kabi kutubxonalar bir vaqtlar keng tarqalgan edi; bugun in, typeof, CSS.supports va @supports yetarli.
  • Intervyu. "Nega userAgent sniffing yomon?", "navigator.onLine ga ishonsa bo'ladimi?" — tez-tez so'raladi.

Xulosa

  • navigator — brauzer va qurilma haqidagi obyekt; uning ko'p qismi xavfsiz kontekst va foydalanuvchi harakatini talab qiladi.
  • onLine + online/offline — false ishonchli, true emas; boshlang'ich holatni qo'lda chizing.
  • navigator.language(s) — taklif uchun; formatlash — sahifa tilida.
  • requestFullscreen / exitFullscreen / fullscreenchange — faqat bosishda; tugma element ichida.
  • wakeLock.request("screen") — tab yashirinsa qo'yib yuboriladi, qaytganda qayta so'raladi; vibrate — Android'da va tegishdan keyin.
  • Brauzer nomini emas, imkoniyatni tekshiring: "wakeLock" in navigator.

Keyingi dars: <dialog> va Popover API JS'dan — modal oyna va popover'larni JavaScript'dan boshqarish: showModal, returnValue, cancel, togglePopover va toggle hodisasi.

Manbalar

  • WHATWG: "HTML Standard" — navigator.onLine, navigator.language — html.spec.whatwg.org
  • WHATWG: "Fullscreen API Standard" — fullscreen.spec.whatwg.org
  • W3C: "Screen Wake Lock API" — w3c.github.io/screen-wake-lock
  • W3C: "Vibration API" — w3c.github.io/vibration
  • MDN: Navigator, "Browser detection using the user agent" — developer.mozilla.org
  • Chrome for Developers: "User-Agent reduction" — developer.chrome.com
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript navigator va qurilma API'lari: tarmoq, til, to'liq ekran va ekran qulfi — IlmHamroh