简体   繁体   中英

Socket.io Event Listeners/Event Handlers Socket.io

One last Hale Mary before I give up on this project. I am trying to create a table of randomly generated words whereby each word that is clicked changes to a corresponding set color. I have the randomly generated words, and an array of corresponding colors. However I cannot get the words to change to their corresponding color on click in the browser real-time using Socket.io - I am almost certain this is because of my lack of knowledge and experience with Socket.io so any help / insight would be great.

Code is below:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Button Test</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
    <link href="/style.css" rel="stylesheet"/>
</head>
<body>
    <button id="startgame">Start</button>
    <div class='game'>
      <h1 id='teamsturn'>Red Team Turn</h1>
      <h1 id='redcounter'></h1>
      <h1 id='bluecounter'></h1>
      <h1 id='winner'></h1>
    <table id="grid" class="squaregrid">
        <tr>
            <td id="1"></td>
            <td id="2"></td>
            <td id='3'></td>
            <td id='4'></td>
            <td id='5'></td>
          </tr>
          <tr>
            <td id='6'></td>
            <td id='7'></td>
            <td id='8'></td>
            <td id='9'></td>
            <td id='10'></td>
          </tr>
          <tr>
            <td id='11'></td>
            <td id='12'></td>
            <td id='13'></td>
            <td id='14'></td>
            <td id='15'></td>
          </tr>
          <tr>
            <td id='16'></td>
            <td id='17'></td>
            <td id='18'></td>
            <td id='19'></td>
            <td id='20'></td>
          </tr>
          <tr>
            <td id='21'></td>
            <td id='22'></td>
            <td id='23'></td>
            <td id='24'></td>
            <td id='25'></td>
          </tr>
        </table>
      </div>
    <script src="/button.js"></script>
</body>
</html>

Back end

var express = require('express')
var socket = require('socket.io') 

//App setup
var app = express();
var server = app.listen(8000, function(){
    console.log('listening to requests on port 8000')
});

//static files
app.use(express.static('public'));

//socket setup
var io = socket(server);

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
  }

const colorsArr = ['red', 'lightgray', 'dimgray','lightgray', 'lightgray','lightgray', 'blue','blue', 'blue', 'red', 'blue','red', 'blue','red', 'blue', 'red', 'red', 'blue', 'red', 'blue','red', 'blue','red', 'blue', 'red'];  
const wordList = [ **REMOVED FOR READABILITY**
  ];


//listening for connection event from browser on connection fires callback function (backend)
io.on('connection', function(socket) {
    console.log('made socket connection', socket.id)

    socket.on('createGrid', function(){
    
        shuffleArray(wordList);
        shuffleArray(colorsArr);
        let gameWords = wordList;
        let gameColors = colorsArr;
        selectedWord = gameWords;
        shuffledColors = gameColors;
        gameRdyWords = []
        for (i=0; i< 25; i++) {
            square = {
                word: selectedWord[i],
                color: shuffledColors[i]
            }
            gameRdyWords.push(square)
        }
        io.sockets.emit('createGrid', gameRdyWords)
    })

//square click to reveal color 
    socket.on('squareClick', function(){
        io.sockets.emit('squareClick', gameRdyWords[0]["color"])
    })
});

Front End

// Make connection (socket for front end)
var socket = io.connect('http://localhost:8000');

//Accessing DOM
let td1 = document.getElementById("1")
let td2 = document.getElementById("2")
let td3 = document.getElementById('3');
let td4 = document.getElementById('4');
let td5 = document.getElementById('5');
let td6 = document.getElementById('6');
let td7 = document.getElementById('7');
let td8 = document.getElementById('8');
let td9 = document.getElementById('9');
let td10 = document.getElementById('10');
let td11 = document.getElementById('11');
let td12 = document.getElementById('12');
let td13 = document.getElementById('13');
let td14 = document.getElementById('14');
let td15 = document.getElementById('15');
let td16 = document.getElementById('16');
let td17 = document.getElementById('17');
let td18 = document.getElementById('18');
let td19 = document.getElementById('19');
let td20 = document.getElementById('20');
let td21 = document.getElementById('21');
let td22 = document.getElementById('22');
let td23 = document.getElementById('23');
let td24 = document.getElementById('24');
let td25 = document.getElementById('25');
let elementArr = [td1, td2, td3, td4, td5, td6, td7, td8, td9, td10, td11, td12, td13, td14, td15, td16, td17, td18, td19, td20, td21, td22, td23, td24, td25]
let startGame = document.getElementById("startgame")

//Send click to server
startGame.addEventListener('click', function(){
    socket.emit('createGrid');
});

//Listen for events from back end to execute on front end 
socket.on('createGrid', function(gameRdyWords) {
    for (i=0; i < elementArr.length; i++) {
   elementArr[i].innerHTML = gameRdyWords[i]["word"];
   //reset all words to black color on clicking start
   elementArr[i].style.color = "black"
    }
    console.log(gameRdyWords)
});


//Square click to reveal color 

document.querySelector('.squaregrid').addEventListener('click', function(){
    socket.emit('squareClick')

});

socket.on('squareClick', function(color) {
   elementArr[i].style.color = color;
});

Here is a link to the completed desired outcome: https://thawing-taiga-40928.herokuapp.com I created this with just JavaScript & html before realizing that unless I wanted to play by myself I had to incorporate some sort of real-time functionality.

Hey jordan i'm guessing that you might this:

// ... your code
// emit with clicked word value
// it's probably e.target.value but i'm not sure
document.querySelector('.squaregrid').addEventListener('click', function(e){
    // so here send the id and word
    // I'm not sure if e.target.id is actually id of the clicked element please check this out.
    // also same for value.
    // maybe console those and when you find correct values send it to server.
    socket.emit('squareClick', { id: e.target.id, word: e.target.value });
});

After this where your backend code

socket.on("squareClick", function (object) {
  // so here find the element contains that word sended from frontend
  let elem = gameRdyWords.find((ch) => ch[0].word === object.word);
  // send object back with color value;
  if(elem) {
    object.color = elem.color;
    io.sockets.emit("squareClick", object);
  }
});

And again in your fronend

// instead of a color you are gonna get the object back.
socket.on('squareClick', function(object) {
   document.getElementById(object.color).style.color = object.color;
   // elementArr[i].style.color = color;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM