【问题标题】:Sending mouse click events using socket.io使用 socket.io 发送鼠标点击事件
【发布时间】:2016-09-02 15:47:51
【问题描述】:

我正在尝试使用 socket.io 和 node.js 从客户端向服务器发出鼠标单击事件。问题是在发出之后,我发送的字典并没有作为一个整体发送。这是我的代码:

客户端:

document.addEventListener('click', function(event){
 console.log("event sent", event.target,event);
 var target = event.target;
 var myClick = {id: target, event: event};
 console.log(myClick);
 socket.emit('myClick', myClick);
})

socket.on('myClick', function(data){
  console.log("event received", data);
  document.querySelectorAll(data.id).dispatchEvent(data.event);
});

在主体上注册单击事件后,控制台会记录此内容:

event sent <body>​…​</body>​ 
MouseEvent {isTrusted: true, screenX: 1145, screenY: 499, clientX: 1040, clientY: 398…}
Object {id: body, event: MouseEvent}

其他页面在收到事件后记录此内容:

event received Object {id: Object, event: Object}

然而,扩展 Object 给了我们这个:

event: Object
  isTrusted: true
  __proto__: Object
id: Object
  __proto__: Object
__proto__: Object

所以它没有接收到整个事件并且 id 没有事件目标。

服务器端:

io.sockets.on('connection', function (socket) {
  console.log("socket connected");
  console.log(socket);
  socket.on('myClick', function (data) {

    console.log("myClick in server.js");
    console.log(socket);
    console.log(data);
    socket.broadcast.emit('myClick', data);
});
});

当服务器在 'myClick' 上接收到某些内容时,它会打印出以下内容:

myClick in server.js
{ id: {}, event: { isTrusted: true } }

如您所见,目标是空的,应该是完整的事件对象只有isTrusted 值。有没有人遇到过这个问题?任何帮助,将不胜感激。我尝试这样做的方式是基于this Stack Overflow 的答案,但他们使用的是 jQuery,而我只是使用 Javascript。

【问题讨论】:

    标签: javascript node.js sockets socket.io dom-events


    【解决方案1】:

    socket.io 尝试将您传递给它的参数转换为 JSON。诸如 DOM 对象之类的东西不能转换为 JSON,并且会触发错误或导致某些内容被忽略。所以,你不能发送event.target。它是一个 DOM 对象,您不能将 DOM 对象发送到您的服务器。您必须发送可以转换为字符串的内容。例如,您可以发送event.target.id

    我建议您做的不是尝试发送包含许多无法发送的东西(例如 DOM 对象)的整个 event 对象,而是创建一个新对象并仅复制您实际需要的属性发送。并且,确保您发送的内容不包含 DOM 对象,并且不包含任何循环引用或其他无法转换为 JSON 的内容。

    我不确切知道您需要 event 对象中的哪些属性,但总体思路如下:

    document.addEventListener('click', function(event){
      // create new object with just the things we need from the event object
      // this must contain only things that can be converted into JSON
      var clickData = {
         id: event.target.id, 
         timeStamp: event.timeStamp,
         type: event.type,
         clientX: event.clientX,
         clientY: event.clientY
      };
      socket.emit('myClick', clickData);
    });
    

    【讨论】:

    • 谢谢!我想发出整个事件的原因是因为我想将相同的事件分派到其他页面。您对如何仅使用 JavaScript 执行此操作有任何建议吗?我现在想到的是发送 X 和 Y 位置,并在接收端创建一个新事件并调度该新事件。
    • @Faisal - 是的,您必须只捕获有关点击位置的相关信息(位置或点击的对象),然后将这些信息发送给其他客户,他们可以尝试模拟相同的动作。请记住,您不能发送 DOM 对象。但是,您可以发送其他客户端可以用来了解正在引用哪个 DOM 对象的识别信息(如 id)。
    【解决方案2】:

    发送对象时尝试 JSON.stringify(objectYouAreSending),接收对象时尝试 JSON.parse(objectYouHaveReceived)。

    不能 100% 确定 socket.io 如何处理来回发送的对象,但这是我要尝试的第一件事。 :)

    【讨论】:

    • 我刚刚将侦听器中的代码更改为:var myClick = {id: target, event: event}; myClick = JSON.stringify(myClick); console.log(myClick); socket.emit('myClick', myClick); 遗憾的是,console.log(myClick) 打印出 {"id":{},"event":{"isTrusted":true }} (这是在对象发送之前打印出来的)。在 socket.io 中如何将字典转换为 JSON 会不会是个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    相关资源
    最近更新 更多