Is there any method to pass live data from one Browser tab another Browser tab by using Javascript

Tags: , , , ,



I created an increment and decrement program but in that, I want to pass data from 1st Browser to 2nd Browser(one tab to another tab).

In Index.html there are two buttons for incrementing and decrementing operations. On the 2nd page only there data will show but my code is working on only same tab. as well as How I can store data after page refresh?

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="/index.js"></script>
    <link href="/index.css" rel="stylesheet" type="text/css">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Live Users in Mall</title>
</head>
<body>
    <div class="container">
        <h1>Live Users in Mall</h1>
    <div class = "card">
        <button onclick = "decrement()">-</button>
        <h2 id = "root">0</h2>
        <button onclick = "increment()">+</button>
    </div>
    </div>
</body>
</html>

index.css

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body{
    background-color: rgb(255, 255, 255);
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    text-align: center;
}
.card{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    padding: 100px;
}

h2{
    margin: 0 50px;
    font-size: 50px;
}
button{
    background-color: #ff9100;
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
    border-radius: 25px;
}
button:hover{
    background-color: rgb(206, 206, 206);
    color: #ff9100;
    border-color: #000 ;
}

index.js

var data = 0;
        document.getElementById("root").innerText = data;

        function decrement() {
            data = data-1;
            if (data <= 0)
            {
                data = 0;
            }

            document.getElementById("root").innerText = data;
            localStorage.setItem("key", data);
        }

        function increment() {
            data = data + 1;
            document.getElementById("root").innerText = data;
            localStorage.setItem("key", data);
        }

2nd Page Name as Showdata

Showdata.html

<!DOCTYPE html>
<html lang="en">
<head>
    <link href="/index.css" rel="stylesheet" type="text/css">
    <script src="/showdata.js"></script>

    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Show Live Data</title>
</head>
<body>
  
  <h3>Users Present in Mall</h3>
    <h2 id="root">0
</h2>  
</body>
</html>

showdata.js

var data = localStorage.getItem("key");
        document.write(data);       
       //output.innerHTML = data;
       //document.getElementById("root").innerText=data;

Can anyone please provide a solution for my problem?

Answer

One (of several) approaches you could use would be to use the BroadcastChannel api. The blurb from MDN states:

The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel.

The index page that has the two buttons:

<!DOCTYPE html>
<html lang="en">
    <head>
        <style>
            * {
                padding: 0;
                margin: 0;
                box-sizing: border-box;
            }
            body{
                background-color: rgb(255, 255, 255);
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%,-50%);
                text-align: center;
            }
            .card{
                display: flex;
                justify-content: center;
                align-items: center;
                height: 100%;
                padding: 100px;
            }

            h2{
                margin: 0 50px;
                font-size: 50px;
            }
            button{
                background-color: #ff9100;
                border: none;
                color: white;
                padding: 15px 32px;
                text-align: center;
                text-decoration: none;
                display: inline-block;
                font-size: 16px;
                margin: 4px 2px;
                cursor: pointer;
                border-radius: 25px;
            }
            button:hover{
                background-color: rgb(206, 206, 206);
                color: #ff9100;
                border-color: #000 ;
            }
        
        </style>
        
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Live Users in Mall</title>
    </head>
    <body>
        <div class="container">
            <h1>Live Users in Mall</h1>
            <div class="card">
                <!--
                    Rather than using `inline` function calls it is 
                    preferable to assign an external event listener.
                    You can easily use the same event handler to 
                    perform both increment and decrement tasks.
                    
                    To aid that the buttons were assign a dataset
                    attribute which is analysed in the click handler.
                -->
                <button data-action='decrement'>-</button>
                <h2>0</h2>
                <button data-action='increment'>+</button>
            </div>
        </div>
        <script>
        
            // Establish the communication channel - this can be (nearly) any name 
            // but the same name is needed for the listeners.
            
            let oChan=new BroadcastChannel( 'tabs' );
            let h2=document.querySelector('div.card h2');
            
            
            // simple function to send a payload of your design
            const sendmessage=function( data ){
                let payload={ 'data':data };
                oChan.postMessage( payload );
            };
    
    
            // fetch the data from localStorage or set as zero
            let data=localStorage.getItem('key');
            if( data == null )data=0;
            else data=Number( data );
            
            h2.innerHTML=data;
            
            
            // assign an event listener for both buttons
            document.querySelectorAll('button[data-action]').forEach( bttn=>{
                bttn.addEventListener('click',function(e){
                    switch( this.dataset.action ){
                        case 'increment':data++;break;
                        case 'decrement':data--;break;
                    }
                    
                    //update storage
                    localStorage.setItem('key',data);
                    
                    // send the message to the "other" page
                    sendmessage( data );
                    
                    // update local display
                    h2.innerHTML=data;
                });
            })
        </script>
    </body>
</html>

And the listening page that is updated in real-time when a button is clicked.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Show Live Data</title>
    </head>
    <body>
        <h3>Users Present in Mall</h3>
        <h2>0</h2>  
        <script>
            // establish listener on same channel
            let oChan=new BroadcastChannel( 'tabs' );
                oChan.addEventListener('message',(e)=>{
                    // process the messages as they arrive
                    document.querySelector('h2').innerHTML=e.data.data
                });
        </script>
    </body>
</html>

The index page establishes a channel to which the listener must also subscribe and sends a simple message ( the datatype is quite flexible ) which is processed in the second window/tab



Source: stackoverflow