为什么在jquery触发器dynamic更新后socket.emit重复?

我试图更新(或更改)在客户端代码中显示的div(“显示器持有人”)的内容,这个div包含html和jQuery,它调用使用socket.emit的div之外的函数,但是一次我replace这个div的内容,函数与socket.emit多次触发,我也使用off()和unbind()函数,但他们似乎并没有工作。 有什么办法dynamic地取代div(显示器持有人)的内容,并让socket.emit只触发一次?

客户端

<!DOCTYPE html> <html> <head> <title>Help!</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> //Globals var displayCounter = 1; //Socket.io client side var socket = io('http://localhost'); socket.on('news', function (data) { console.log(data); $('#message-displayer').append("<b> Server says: </b>"+data.msg+"<br>"); }); socket.on('client-answer', function (data) { console.log(data); $('#message-displayer').append("<b> Server says: </b>"+data.msg+"<br>"); socket.emit('message', { msg: 'my data from client' }); }); //emitter function function sendData(data){ socket.emit("client-message", { msg:data }); } </script> <style> #display-holder{ position: absolute; margin: auto; top: 0; right: 0; bottom: 0; left: 0; width: 500px; height: 300px; background-color: #ccc; border-radius: 3px; text-align:center } .display-holder-nodes{ display: inline-block; border: 1px solid black; width: 95%; } button, input{ width: auto; height: auto; padding: 10px; margin-top: 16px; } #message-displayer{ height:70%; overflow-y: scroll;} #control-panel{ height:25%; text-align:center;} </style> </head> <body> <div id="display-holder"> <div id="message-displayer" class="display-holder-nodes"></div> <div id="control-panel" class="display-holder-nodes"> <input type="text" id="clientInput"> <button id="sendMessage">Send message</button> <button id="changeDisplay">Change display</button> </div> <script> //jQuery handlers (will be replace when clicking "#changeDisplay" btn) $(document).on('click', '#sendMessage', function(){ $('#message-displayer').append("<b> You said: </b>"+$('#clientInput').val()+"<br>"); sendData($("#clientInput").val()); $('#clientInput').val(''); }); </script> </div> <script> //jQuery handlers $(document).on('click', '#changeDisplay', function(){ displayCounter++; //html and jquery to be inserted dynamically $("#display-holder").empty().off().unbind().html(' <div id="display-holder">'+ '<div id="message-displayer" class="display-holder-nodes"><h3>Dislplay #'+displayCounter+'</h3></div>'+ '<div id="control-panel" class="display-holder-nodes">'+ '<input type="text" id="clientInput">'+ '<button id="sendMessage">Send message</button>'+ '<button id="changeDisplay">Change display</button> '+ '</div>'+ '<script>'+ '$(document).on("click", "#sendMessage", function(){'+ ' $("#message-displayer").append("<b> You said: </b>"+$("#clientInput").val()+"<br>");'+ 'sendData($("#clientInput").val());'+ ' $("#clientInput").val("");'+ '});'+ '</sc'+'ript>'+ '</div>'); }); </script> </body> </html> 

服务器端

 var app = require('http').createServer(handler) var io = require('socket.io')(app); var fs = require('fs'); app.listen(80, function(){ console.log('App listening on port 80'); }); function handler (req, res) { fs.readFile(__dirname + '/public/index.html', function (err, data) { if (err) { res.writeHead(500); return res.end('Error loading index.html'); } res.writeHead(200); res.end(data); }); } io.on('connection', function (socket) { socket.emit('news', { msg: 'hello client' }); socket.on('message', function (data) { console.log('Client says: ', data); }); socket.on('client-message', function (data) { console.log('Client says: ', data); socket.emit('client-answer', { msg: 'You sent me: '+data.msg }); }); }); 

您将附加事件来document和移除附加到display_holder事件。


正如文件所述

.on()方法将事件处理程序附加到jQuery对象中当前选定的一组元素


.on()更改为$("#display_holder").on('click'