怎样解决支持同一元素句柄可以绑定多个监听函数问题?

问题描述:

支持同一元素句柄可以绑定多个监听函数

我们来分析这个问题,看下面的例子:

这里我们得理解

1)同一元素是意思?

2) 绑定多个监听函数?

如下面例子


window.οnlοad=function(){//1个监听函数

 alert("1");}//没有输出结果

window.οnlοad=function(){/2个监听函数

 alert("2");}//没有输出结果

window.οnlοad=function(){//3个监听函数

 alert("3");}//没有输出结果


我们发现无法绑定输出3把1,2覆盖,所以我们得出一个结论就是:

传统事件无法多个监听函数

那么这时我们就得思考事件绑定都有那些方法?

1)传统事件绑定

2)现代事件绑定

既然传统事件绑定无法实现,那么我们就思考现代事件绑定:

w3c:addEventListenner()

ie:attachEvnt

如何来建立这个函数呢?

首先我们要做兼容是必然

做兼容套路

无非就是把浏览器的不同情况往if else里面套。

所以我们第一步先写一个函数

function addEvent(){

if()

{}

else

{}

}

第二步我们的思考函数怎么设置参的问题?

既然是支持同一元素,那么我们就必须要一个对像,用obj表示

还有参数我们的思考addEventListener与attach有什么共同特点的参数?

addEventListener(event,function,可选参数);

attachEvent(event,function);

所以我们可以利用它们共同参数的相似特点来设定type和事件函数fn来表示

所以代码如下:

function addEvent(obj,type,fn){

if()

{}

else

{}

}

第三步就是做w3c与ie兼容,根据它们的用法来写

function addEvent(obj,type,fn){

if(typeof obj.addEventListener!="undefined"){

obj.addEventListener(type,fn,false);//w3c




}

else if(typeof obj.attchEvent!="undefined"){

obj.attachEvent('on'+type,fn);//ie


}}

现在我们就可以把上面的1 2 3的例子拿进行测试

addEvent(window,"load",function(){

alert(1);});//1这里window对应obj,load对应函数事件名onload,function则对应function

addEvent(window,"load",function(){

alert(2);});//2

addEvent(window,"load",function(){

alert(3);});//3

从这个例子我们可以得到一些思考程序问题的一般方法:

第一步分类试探法

也就是一谈到事件绑定,我们立马联想到是传统事件与现代事件绑定两种类型

第二我称之为排除

当利用这两方法都去尝试,发现传统不行,这就是排除法

第三我觉得参数的设定有点像归纳法

找出它们两的共性来设置参数



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
了解了您的需求后,您需要对服务器端代码进行以下修改: 1. 对于每个连接到服务器的客户端,创建一个新的线程来处理该客户端的消息。 2. 为了让多个客户端都能连接到服务器,您需要将服务器端的 `accept` 函数放到一个循环中,以便能够接受多个客户端的连接请求。 3. 当服务器收到某个客户端的消息时,需要将该消息转发给所有连接到服务器的客户端。 下面是修改后的服务器端代码,您可以参考一下: ```c #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <WinSock2.h> #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif #pragma comment(lib,"ws2_32.lib") SOCKET g_clientSockets[10]; int g_clientCount = 0; DWORD WINAPI ClientThread(LPVOID lpParam) { SOCKET clientSocket = *(SOCKET*)lpParam; char recvBuf[50], sendBuf[50]; while (1) { // 接收客户端消息并处理 int ret = recv(clientSocket, recvBuf, 50, 0); if (ret <= 0) { break; } printf("Received message from client: %s\n", recvBuf); // 转发消息给所有客户端 for (int i = 0; i < g_clientCount; i++) { if (g_clientSockets[i] != clientSocket) { send(g_clientSockets[i], recvBuf, strlen(recvBuf) + 1, 0); } } } // 关闭客户端套接字 closesocket(clientSocket); // 从全局变量中移除该客户端套接字 for (int i = 0; i < g_clientCount; i++) { if (g_clientSockets[i] == clientSocket) { g_clientCount--; memmove(&g_clientSockets[i], &g_clientSockets[i + 1], (g_clientCount - i) * sizeof(SOCKET)); break; } } return 0; } int main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return -1; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return -1; } // 创建套接字并绑定到本地地址 SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_port = htons(6000); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); // 开始监听客户端连接请求 listen(sockSrv, 5); while (1) { // 接受客户端连接并处理消息 SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len); // 将新连接的客户端套接字加入全局变量 g_clientSockets[g_clientCount++] = sockConn; // 创建新线程来处理该客户端的消息 HANDLE hThread = CreateThread(NULL, 0, ClientThread, &sockConn, 0, NULL); // 关闭线程句柄 CloseHandle(hThread); } closesocket(sockSrv); WSACleanup(); return 0; } ``` 同时,您还需要对客户端代码进行修改,以便让它能够接收其他客户端发送过来的消息。下面是修改后的客户端代码,您可以参考一下: ```c #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <WinSock2.h> #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif #pragma comment(lib,"ws2_32.lib") DWORD WINAPI ReceiveThread(LPVOID lpParam) { SOCKET sockClient = *(SOCKET*)lpParam; char recvBuf[50]; while (1) { // 接收服务器的消息并打印出来 int ret = recv(sockClient, recvBuf, 50, 0); if (ret <= 0) { break; } printf("Received from server: %s\n", recvBuf); } return 0; } int main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return -1; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return -1; } // 创建套接字并连接到服务器 SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); // 创建新线程来接收服务器的消息 HANDLE hThread = CreateThread(NULL, 0, ReceiveThread, &sockClient, 0, NULL); char sendBuf[50]; while (1) { // 读取用户输入的消息并发送给服务器 printf("Input message to send: "); fgets(sendBuf, 50, stdin); send(sockClient, sendBuf, strlen(sendBuf) + 1, 0); } // 关闭线程句柄 CloseHandle(hThread); closesocket(sockClient); WSACleanup(); return 0; } ``` 请注意,上述代码中仅为示例代码,可能还需要您根据实际情况进行一些修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值