javascript - Tunnista muiden saman verkkotunnuksen välilehtien/ikkunoiden läsnäolo


Jos minulla on kaksi (tai useampia) välilehteä auki samalla verkkotunnuksella, onko yksinkertainen tapa havaita toisen läsnäolo (jotta voin hallita, mitä laskelmia teen)? Ymmärrän, että on olemassa window.open() -funktio, mutta en avaa yhtä ikkunaa toisesta. Sen sijaan kuvitellaan, että käyttäjä menee kahdella välilehdellä sivustoon mydomain.com.

Olen alkanut kirjoittaa koodia käyttäen HTML5:n paikallista tallennusta, jossa jätän ajoittain viestejä ja tarkistan viestejä, mutta tämä vaikuttaa hieman monimutkaiselta.

Vastaus #1

Se on mielenkiintoinen ongelma.

Voimme kokeilla näitä API:ja: postMessage, sessionStorage, localStorage, webRtc.


BroadcastChannel sopii erittäin hyvin:

BroadcastChannel sallii saman alkuperän skripteille, mutta eri selauskonteksteille (ikkunat, työntekijät) lähettää toisilleen viestejä.

BroadcastChannel-rajapinta edustaa nimettyä kanavaa, johon minkä tahansa tietyn alkuperän selauskonteksti voi liittyä. Se mahdollistaa viestinnän eri asiakirjojen (eri ikkunoissa, välilehdissä, kehyksissä tai iframeissa) välillä samalla alkuperällä. Viestit lähetetään ja ne vastaanotetaan viestitapahtumana, joka laukaistaan kaikissa kanavaa kuuntelevissa BroadcastChannel-olioissa.

Se eroaa postMessage-rajapinnasta siinä, että lapsi-ikkunoita ei ole tarkoitettu ilmoitettavaksi vanhemmassa sivussa. Tällä tavalla ei ole enää vanhempia eikä lapsia.

Esimerkkilähetys:

new BroadcastChannel('myapp').postMessage('Hello?');

Esimerkin vastaanottaminen:

new BroadcastChannel('myapp').addEventListener('message', function(e){
  console.log(e.data) 
})

Näin voimme laskea välilehtiä tai jopa tiedottaa nykyisistä aktiivisista tiloista muille välilehdille jne.

Käyttöpalautetta tämän viestin jälkeen. BroadcastChannel API on melko yksinkertainen, mutta sallii arkkitehtuurien uudelleenarvioinnin.

Tämä sallii tuontimoduulien keskustella keskenään, tämä yksinkertaistaa skriptien koostamista.

En tunne tarvetta verkkopakattuihin koottuihin skripteihin monimutkaisten asioiden rakentamiseksi. Voimme jakaa objekteja - json-muodossa - kanavien kautta, kutsua «palvelua» tarvittaessa, erottaa logiikat, mallipohjat, tehtaat, tapahtumat, palvelut paljon helpommin.

Tämä on täysin kohdallaan muistin käytön ja suorituskyvyn osalta. Voimme luoda monia kanavia syöttämään rinnakkain suurta datavirtaa, tällä on vähän vaikutusta RAM-muistiin/prosessoriin ja käyttöliittymän reagointikykyyn.

Vähemmän muuttujia, vähemmän logiikkaa, lähetetyt tiedot menevät suoraan roskiin. Koodausstyyli on melko samanlainen kuin websoketeissa, tapahtumapohjainen, tämä on vain paikallinen(t) soketti(t).

Tapahtumapohjainen arkkitehtuuri (EDA) on ohjelmistoarkkitehtuurin paradigma, joka edistää tapahtumien tuottamista, havaitsemista, kuluttamista ja niihin reagoimista.


[MDN] Lähetys_kanava_API

https://caniuse.com/#feat=broadcastchannel

Vastaus #2

Laskurin asettaminen localStorageen (kasvattamalla laskuria, kun avataan uusi välilehti) ja luottaminen onbeforeunloadiin laskurin vähentämiseksi, kun välilehti suljetaan, ei ole luotettava ratkaisu, koska jos pakotat selaimen sulkeutumaan, onbeforeunload-kuuntelijaa ei suoriteta, eikä siten laskuria vähennetä.

Sanotaan, että sinulla on avoinna 1 välilehti ja paikallisen tallennuksen "tabs_opened" -laskuri on 1. Jostain syystä sinun täytyy pakottaa selaimesi sulkeutumaan. Kun avaat selaimen uudelleen ja vierailet samalla verkkosivustolla, "tabs_opened"-laskurista tulee nyt 2, koska "tabs_opened"-laskuria ei vähennetty.

Olen pahoillani, sanomani ei ole tarkalleen vastaus (mutta en voi lisätä kommenttia, koska minulla ei ole tarpeeksi mainetta kommentin lisäämiseen). Haluan vain todella tuoda esille tämän erityistapauksen.