聊天室1.0版

写了几天1.0终于写好了,不容易啊
客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <stdlib.h>

#define SIZE 1024
#define PORT  9999

int flag1 = 0;
char myname [20];
char password[20];

char msg1[1024];        // 保存聊天信息

struct Msg
{
    char msg[SIZE];     //消息内容
    char name[20];       //用户名
    char fromname[20];      //发送消息的用户名
    char toname[20];      //要发送消息的用户名
    char password[20];  //用户密码
    int socket;         
    int cmd;            //执行的命令
    int flag;
};

struct Msg msg;     // 全局变量两个线程共享
//主页面
void interface()
{
    printf ("1、注册\n");
    printf ("2、登陆\n");
    printf ("3、退出\n");
}

//普通用户的界面
void noruser()
{
    printf ("1、查看当前在线用户\n");
    printf ("2、进入群聊\n");
    printf ("3、进入私聊\n");
    printf ("4、查看聊天记录\n");
    printf ("5、更改用户密码\n");
    printf ("6、注销当前用户\n");
    printf ("7、设置个性签名\n");
    printf ("8、文件传输\n");
    printf ("9、退出聊天室 返回登陆界面\n");
}

//查看当前在线人数
int online (int socketfd)
{
    struct Msg msg;
    msg.flag = 1;
    msg.cmd = 10;

    write (socketfd, &msg, sizeof (msg));
}

//群聊
void chat2(int socketfd, char *name)
{
    struct Msg msg;
    msg.flag = 2;
    msg.cmd = 10;

    strcpy (msg.toname, "all");

    printf ("请输入要发送的内容: \n");
    fgets(msg.msg, 1024, stdin);
    strcpy (msg.fromname, name);

    write (socketfd, &msg, sizeof(msg));
}

//私聊
void chat (int socketfd,char *name)
{
    struct Msg msg;
    msg.flag = 3;
    //msg.cmd = 10;
    printf ("请输入要发送的对象的名称:\n");
    scanf ("%s", msg.toname);
    while(getchar() != '\n');

    printf ("请输入要发送的内容:\n");
    scanf ("%s", msg.msg);
    while(getchar() != '\n');

    strcpy (msg.fromname, name);

    write (socketfd, &msg, sizeof (msg));
    //printf("qwwerterter\n");
}

//更改密码
void change_pw (int socketfd,char *name)
{
    struct Msg msg;
    msg.flag = 5;
    msg.cmd = 10;
    printf ("请输入你要更改密码的用户:\n");
    scanf ("%s", name);
    while(getchar() != '\n');

    printf ("请输入更改的密码:\n");
    scanf ("%s", msg.msg);
    while(getchar() != '\n');

    strcpy (msg.fromname, name);
    write (socketfd, &msg, sizeof (msg));
}

// 用来保存收到的聊天信息
int keep_msg(char * msg1,struct Msg msg)
{
    sqlite3 * database;
    // 打开数据库
    int ret = sqlite3_open("histroy.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("\t打开数据库失败\n");
        return;
    }

    char *errmsg = NULL;
    char *sql = "create table if not exists histroy(fromname TEXT, tonamed TEXT, msg TEXT)";
    ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    // 往histroy表中添加信息
    char buf[100];
    sprintf (buf, "insert into histroy values('%s','%s','%s')",msg.fromname,msg.toname,msg1);
    ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("\t数据库操作失败:%s\n", errmsg);
        return -1;
    }

    sqlite3_close(database);
}


// 打印群聊历史记录
void chat1_hst()
{
    system("clear");
    printf ("\t*************************** 网络聊天室 *****************************\n\n\n");
    printf ("\t群聊历史记录:                                                      \n");

    sqlite3 * database;
    // 打开数据库
    int ret = sqlite3_open("histroy.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("\t打开数据库失败\n");
        return;
    }

    // 获取histroy表中的信息
    char *errmsg = NULL;
    char **resultp = NULL;
    int nrow, ncolumn;
    char *sql = "select * from histroy";
    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return;
    }
    int i;
    for (i = 4; i < (nrow+1)*ncolumn; i += 3)
    {
        if(strcmp(resultp[i], "all") == 0)
        {
            printf ("%s\n", resultp[i+1]);
        }
    }
    sqlite3_free_table(resultp);

    // 关闭数据库
    sqlite3_close(database);
}

// 打印私聊历史记录
void chat2_hst()
{
    system("clear");
    printf ("\t*************************** 网络聊天室 *****************************\n\n\n");
    printf ("\t私聊历史记录:\n");

    sqlite3 * database;
    // 打开数据库
    int ret = sqlite3_open("histroy.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("\t打开数据库失败\n");
        return;
    }

    // 获取histroy表中的信息
    char *errmsg = NULL;
    char **resultp = NULL;
    int nrow, ncolumn;
    char *sql = "select * from histroy";
    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return;
    }
    int i;
    for (i = 4; i < (nrow+1)*ncolumn; i += 3)
    {
        if(strcmp(resultp[i], "all") != 0)
        {
            printf ("%s\n", resultp[i+1]);
        }
    }
    sqlite3_free_table(resultp);

    // 关闭数据库
    sqlite3_close(database);
}

// 查看聊天记录
void dis_histroy(int socketfd)
{
    printf ("\n\t a、查看群聊记录\n\t b、查看个人聊天记录\n\t");
    printf ("\n\t***** 请选择: ");
    switch (getchar())
    {
        case 'a':
            chat1_hst();
            break;
        case 'b':
            chat2_hst();
            break;
    }
    printf ("\n\t回车键返回  ");
    getchar();
}

//用户注销
void logout (int socketfd, char *name)
{
    struct Msg msg;
    msg.flag = 6;
    msg.cmd = 10;

    strcpy (msg.fromname, name);
    write (socketfd, &msg, sizeof (msg));

    flag1 = 1;
}

//普通用户界面工作函数
void work(int socketfd, char *name)
{
    char ch[10];

    system ("clear");
    int i = 1;
    while(i)
    {
        noruser();
        fgets (ch, 2, stdin);

        while (getchar() != '\n');

        switch (ch[0])
        {
            case '1':
                online (socketfd);
                break;
            case '2': //群聊
                chat2(socketfd, name);
                break;
            case '3':  //私聊
                chat (socketfd, name);
                break;
            case '4':
                dis_histroy(socketfd);
                getchar();
                break;
            case '5':  //更改用户密码
                change_pw (socketfd, name);
                break;  
            case '6':
                logout (socketfd,name);
                i = 0;
                return;
            case '9':
                logout (socketfd, name);
                exit (0);
                break;
        }
    system ("clear");
    }   
}


//注册账号
void reg(int socketfd)
{
    struct Msg msg;

    msg.cmd = 1;
    printf ("请输入用户名:\n");
    //fgets (name, 20, stdin);
    //strcpy (msg.name, name);
    scanf("%s",msg.name);
    while(getchar() != '\n');


    printf ("请输入密码:\n");
    //fgets(password, 20, stdin);
    //strcpy (msg.password, password);
    scanf ("%s",msg.password);
    while(getchar() != '\n');


    write (socketfd, &msg, sizeof(msg));

    read (socketfd, &msg, sizeof(msg));


    if (msg.cmd == 1001)
    {
        printf ("注册成功\n");
    }
    else if (msg.cmd == -1)
    {
        printf ("注册失败\n");
    }

}


//线程分离函数
void * readMsg(void *v)
{
    int socketfd = (int)v;
    struct Msg msg;

    while (1)
    {
        if(flag1 == 1)
        {
            flag1 = 0;
            pthread_exit(NULL);
        }
        read (socketfd, &msg, sizeof(msg));
        switch (msg.flag)
        {
            case 1:
                printf ("在线用户: %s\n", msg.name);
                sleep(2);
                system ("clear");
                break;
            case 2:
                printf("%s 给所有人发了一条消息:%s\n",msg.fromname, msg.msg);
                sprintf (msg1,"%s 向 %s 发送一条信息:%s\n",msg.fromname, msg.toname, msg.msg);
                keep_msg(msg1,msg);
                break;
            case 3:   // 私聊
                printf ("%s 给你发一条消息:%s\n", msg.fromname, msg.msg);
                sprintf (msg1,"%s 向 %s 发送一条信息:%s\n",msg.fromname, msg.toname, msg.msg);
                keep_msg(msg1,msg);
                break;
            case 5:
                printf ("%s 更改了用户密码\n", msg.fromname);
                break;
            case 6:
                printf ("%s 进行了注销\n", msg.fromname);
                break;
            case 9:
                exit (0);
                break;
        }
    }
}


//登陆账号
void Login(int socketfd)
{
    struct Msg msg;
    msg.cmd = 2;
    printf ("请输入用户名:\n");
    //fgets (name, 20, stdin);
    //strcpy (msg.name, name);
    scanf("%s",msg.name);
    while(getchar() != '\n');

    printf ("请输入密码:\n");
    //fgets(password, 20, stdin);
    //strcpy (msg.password, password);
    scanf ("%s",msg.password);
    while(getchar() != '\n');

    write (socketfd, &msg, sizeof(msg));

    read (socketfd, &msg, sizeof(msg));

    if (msg.cmd == 1001)
    {
        printf ("登陆成功\n");
        pthread_t id;
        pthread_create(&id, NULL, readMsg,  (void *)socketfd);

        pthread_detach(id); // 线程分离

        work(socketfd,msg.name);
    }
    else if (msg.cmd == -1)
    {
        printf ("登陆失败\n");
    }

}


// 客户端向服务器发送数据
void ask_server(int socketfd)
{
    char ch[3];

    while (1)
    {
        interface();
        printf ("请输入操作命令\n");
        fgets (ch, 2, stdin);

        while (getchar() != '\n');

        switch (ch[0])
        {
            case '1':  //注册
                reg(socketfd);
                break;
            case '2':  //登陆
                Login(socketfd);
                break;
            case '3':  //退出
                exit (0);
                break;
            default:
                printf ("您输入有误 请重新输入\n");
                sleep(1);
                break;
        }

        system ("clear");
    }
}


int main()
{   
    // 创建与服务器通信的套接字
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd == -1)
    {
        perror ("socket");
        return -1;
    }

    // 连接服务器
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family  = AF_INET;     // 设置地址族
    addr.sin_port    = htons(PORT); // 设置本地端口
    inet_aton("127.0.0.1",&(addr.sin_addr));


    // 连接服务器,如果成功,返回0,如果失败,返回-1
    // 成功的情况下,可以通过socketfd与服务器进行通信
    int ret = connect(socketfd, (struct sockaddr *)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror ("connect");
        return -1;
    }

    printf ("成功连上服务器\n");

    ask_server(socketfd);

    // 关闭套接字
    close(socketfd);

    return 0;
}

服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sqlite3.h>
#include <stdlib.h>

#define PORT  9999
#define SIZE 1024

struct Msg
{
    char msg[SIZE];     //消息内容
    char name[20];       //用户名
    char fromname[20];      //发送消息的用户名
    char toname[20];      //要发送消息的用户名
    char password[20];  //用户密码
    int Socket;         //用户通信的socket
    int cmd;            //执行的命令
    int flag;
};


//初始化套接字,返回监听套接字
int init_socket ()
{
    //1、创建套接字
    int listen_socket = socket (AF_INET, SOCK_STREAM, 0);
    if (listen_socket == -1)
    {
        perror ("socket");
        return -1;
    }

    //2、命名套接字,绑定本地的ip地址和端口
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof (addr));  //置零
    addr.sin_family = AF_INET;  // 设置地址族
    addr.sin_port   = htons(PORT); //设置本地端口
    addr.sin_addr.s_addr = htonl (INADDR_ANY); //使用任意的ip地址

    int ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror("bind");
        return -1;
    }

    //监听本地套接字
    ret = listen (listen_socket, 5);
    if (ret == -1)
    {
        perror ("listen");
        return -1;
    }

    printf ("等待客户端连接.....\n");

    return listen_socket;
}

//处理客户端连接,返回与连接上的客户端通信的套接字
int MyAccept (int listen_socket)
{
    struct sockaddr_in client_addr;  //用来保存客户端的ip和端口信息
    int len = sizeof (client_addr);
    int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
    if (client_socket == -1)
    {
        perror ("accept");
    }

    printf ("成功接收一个客户端: %s\n",inet_ntoa(client_addr.sin_addr));

    return client_socket;
}

//进行注册
int reg(int client_socket, struct Msg *msg)
{
    printf ("进行注册\n");

    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char *sql = "create table if not exists user(name TEXT, password TEXT, socket INTEGER,primary key(name))";
    ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }
    // insert into student values(id, name, sex, age);
    char buf[100];
    sprintf (buf, "insert into user values('%s', '%s', %d)", msg->name, msg->password,msg->Socket);
    ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        msg->cmd = -1;
    }
    else
    {
        msg->cmd = 1001;
    }
    // 关闭数据库
    sqlite3_close(database);

    printf ("%d\n",msg->cmd);
    write (client_socket, msg, sizeof(struct Msg));

}

// 1、exec传过来的参数
// 2、代表查询的列数
// 3、char** value  代表一条记录的值 char *value[] = {"1", "zhang1", "M", "12"};
// 4、char** name   代表每一列的字段 char *name[]  = {"id", "name", "sex", "age"};

// 每查到一条记录,该函数被调用一次
//查询的回掉函数
int MSG(void* v, int num, char** value, char** name)
{
    struct Msg *msg = (struct Msg *)v;
    if (strcmp(value[0], msg->name) == 0 && strcmp(value[1], msg->password) == 0)
    {
        printf ("登陆成功\n");
        msg->cmd = 1001;
    }
    return 0;  // 函数内部一定要返回一个0
}


//登陆账号
int Login(int client_socket, struct Msg *msg)
{
    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char *sql = "select * from user";
    ret = sqlite3_exec(database, sql, MSG, msg, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }
    if (msg->cmd != 1001)
    {
        printf ("登陆失败\n");
        msg->cmd = -1;
    }



    // 关闭数据库
    sqlite3_close(database);

    write (client_socket, msg, sizeof(struct Msg));
}

//查看当前在线用户
int noruser (int client_socket, struct Msg *msg)
{
    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char **resultp = NULL;
    int nrow, ncolumn;
    char sql[SIZE];
    sprintf (sql, "select * from user where socket > %d", -1); //查找大于-1的socket
    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }   
    int i;
    for (i = 3; i < (nrow+1)*ncolumn; i += 3)
    {
        //if (i % ncolumn == 0)
        //  printf ("-8%s",resultp[i]);

        strcpy (msg->name, resultp[i]);
        write (client_socket, msg, sizeof (struct Msg));
    }

    sqlite3_free_table(resultp);
    // 关闭数据库
    sqlite3_close(database);
}
//更改密码
int change_pw (int client_socket, struct Msg *msg)
{
    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char sql[SIZE];
    sprintf (sql, "update user set password = '%s' where name = '%s'", msg->msg, msg->fromname);
    ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    // 关闭数据库
    sqlite3_close(database);

    write (client_socket,msg, sizeof (struct Msg));
}

//更新套接字
int update_socket (int client_socket, struct Msg *msg)
{
        sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char sql[SIZE];
    sprintf (sql, "update user set socket = %d where name = '%s'", client_socket, msg->name);
    ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    // 关闭数据库
    sqlite3_close(database);
}

//套接字结束时置-1
int update_Socket (int client_socket, struct Msg *msg)
{

    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    char *errmsg = NULL;
    char sql[SIZE];
    sprintf (sql, "update user set socket = %d where name = '%s'", -1, msg->fromname);
    ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    // 关闭数据库
    sqlite3_close(database);
}

//群聊
int chat2 (int client_socket, struct Msg *msg)
{
    printf ("%s 发一次群消息\n", msg->fromname);

    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    // 3、char ***resultp: char *resultp[] = {"id", "name", "sex", "age", "1", "zhang", "M", "12","2".....};
    // 4、nrow: 多少行数据
    // 5、ncolumn: 多少列数据
    char *errmsg = NULL;
    char **resultp = NULL;
    int nrow, ncolumn;
    char *sql = "select * from user";
    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }   
    int i;
    for (i = 5; i < (nrow+1)*ncolumn; i += 3)
    {
        if ((atoi(resultp[i]) != 0))
        {
            write (atoi(resultp[i]), msg, sizeof (struct Msg));
        }
    }

    sqlite3_free_table(resultp);
    // 关闭数据库
    sqlite3_close(database);

}

//私聊
int chat (int client_socket, struct Msg *msg)
{
    printf ("%s 要给 %s 发一条消息\n", msg->fromname, msg->toname);

    sqlite3 * database;

    // 打开数据库
    int ret = sqlite3_open("user.db", &database);
    if (ret != SQLITE_OK)
    {
        printf ("打开数据库失败\n");
        return -1;
    }

    // 3、char ***resultp: char *resultp[] = {"id", "name", "sex", "age", "1", "zhang", "M", "12","2".....};
    // 4、nrow: 多少行数据
    // 5、ncolumn: 多少列数据
    char *errmsg = NULL;
    char **resultp = NULL;
    int nrow, ncolumn;
    char *sql = "select * from user";
    ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }   
    int i;
    for (i = 5; i < (nrow+1)*ncolumn; i += 3)
    {
        if ((atoi(resultp[i]) != 0) && (strcmp(resultp[i-2],msg->toname) == 0))
        {
            write (atoi(resultp[i]), msg, sizeof (struct Msg));
        }
    }

    sqlite3_free_table(resultp);
    // 关闭数据库
    sqlite3_close(database);
}

//进行注销
void logout (int client_socket, struct Msg *msg)
{
    //strcpy (name, msg->name);
    write(client_socket, msg, sizeof(struct Msg));
}

//把 负责处理客户端通信的函数改成线程的工作函数
void * hanld_client(void* v)
{
    int client_socket = (int)v;
    struct Msg msg;

    while (1)
    {
        //从客户端读一个结构体
        int ret = read (client_socket, &msg, sizeof (msg));
        if (ret == -1)
        {
            perror ("read");
            break;
        }

        //代表客户端退出
        if (ret == 0)
        {
            update_Socket (client_socket, &msg);
            sleep(1);
            printf ("客户端退出\n");
            break;
        }

        switch (msg.cmd)
        {
            case 1:         //客户端进行注册
                reg (client_socket, &msg);
                break;
            case 2:         //客户端进行登陆
                Login(client_socket, &msg);
                update_socket(client_socket, &msg);
                break;
            case 3:         //客户端退出
                exit(0);
                break;
        }

        switch (msg.flag)
        {
            case 1:
                noruser (client_socket, &msg);
                break;
            case 2:
                chat2 (client_socket, &msg);
                break;
            case 3:
                chat(client_socket, &msg);
                break;
            case 5:
                change_pw (client_socket, &msg);
                break;
            case 6:
                logout (client_socket, &msg);
                break;
            case 9:
                exit(0);
                break;
        }
    }
}


int main ()
{
    //初始化套接字
    int listen_socket = init_socket();

    while (1)
    {
        //获取与客户端连接的套接字
        int client_socket = MyAccept(listen_socket);

        //创建一个线程去处理客户端的请求,主线程依然负责监听
        pthread_t id;
        pthread_create(&id, NULL, hanld_client, (void *)client_socket);
        pthread_detach(id); //线程分离
    }

    close (listen_socket);

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 为了写一个能够自适应页面大小的聊天室前端代码模板,可以使用CSS媒体查询来实现响应式设计,以便能够根据页面的大小来自动调整布局和大小。 以下是一个简单的代码模板: ``` <style> body { margin: 0; width: 100%; overflow-x: hidden; } #chatroom { width: 100%; max-width: 500px; } @media screen and (max-width: 500px) { #chatroom { width: 100%; } } </style><div id="chatroom"> <!-- Your chatroom code goes here --> </div> ``` ### 回答2: 聊天室前端代码模板可采用以下方式实现页面自适应大小: 1. HTML结构: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>聊天室</title> <style> #chat-container { display: flex; flex-direction: column; height: 100vh; } #chat-messages { flex: 1; overflow-y: auto; } #input-area { display: flex; justify-content: center; align-items: center; padding: 10px; } #input-area input { width: 80%; height: 30px; } </style> </head> <body> <div id="chat-container"> <div id="chat-messages"> <!-- 聊天消息显示区域 --> </div> <div id="input-area"> <input type="text" id="input-message" placeholder="请输入消息内容"> <button id="send-button">发送</button> </div> </div> <script src="script.js"></script> </body> </html> ``` 2. CSS样式: 上述HTML结构中的样式设置实现了聊天室页面的自适应大小效果。 - `#chat-container`使用了flex布局,容器高度设置为100vh,即占据整个可视区域的高度。 - `#chat-messages`设置为flex: 1,表示自动占据剩余空间,并将超出容器高度的内容进行滚动显示。 - `#input-area`使用了flex布局,内容居中显示,并添加了一定的内边距。 - `#input-area input`设置了宽度为80%,高度为30px。 3. JavaScript交互: 在script.js文件中,可以通过获取页面元素和添加事件监听器等方式实现聊天室的功能。 ```javascript window.onload = function() { var sendButton = document.getElementById("send-button"); var inputMessage = document.getElementById("input-message"); var chatMessages = document.getElementById("chat-messages"); sendButton.addEventListener("click", function() { var messageText = inputMessage.value; var messageElement = document.createElement("div"); messageElement.textContent = messageText; chatMessages.appendChild(messageElement); inputMessage.value = ""; }); }; ``` 在以上JavaScript代码中,获取了发送按钮、输入框和聊天消息显示区域的元素,并对发送按钮的"click"事件进行监听。当点击发送按钮时,获取输入框中的文本内容,创建一个div元素用于显示消息,并将其添加到聊天消息显示区域的末尾。之后,清空输入框的内容,以便继续输入下一条消息。 通过以上HTML、CSS和JavaScript的组合实现,聊天室前端代码模板就能够自适应页面大小,并具备了基本的消息发送和显示功能。 ### 回答3: 要实现一个能够自适应页面大小的聊天室前端代码模板,我们可以运用一些HTML、CSS和JavaScript的知识。以下是一个简单的代码模板: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>自适应聊天室</title> <style> body { margin: 0; padding: 0; font-family: Arial, sans-serif; } #chatroom { width: 100%; height: 100vh; display: flex; flex-direction: column; } #message-container { flex: 1; overflow-y: scroll; padding: 10px; } #input-container { display: flex; padding: 10px; } #input-field { flex: 1; margin-right: 10px; padding: 5px; } #send-button { padding: 5px 10px; background-color: #007bff; color: white; border: none; } </style> </head> <body> <div id="chatroom"> <div id="message-container"></div> <div id="input-container"> <input type="text" id="input-field" placeholder="请输入消息..."> <button id="send-button">发送</button> </div> </div> <script> // 获取DOM元素 const messageContainer = document.getElementById('message-container'); const inputField = document.getElementById('input-field'); const sendButton = document.getElementById('send-button'); // 监听发送按钮点击事件 sendButton.addEventListener('click', () => { const message = inputField.value; // 发送消息逻辑... // 清空输入框 inputField.value = ''; }); // 监听输入框回车键事件 inputField.addEventListener('keyup', (event) => { if (event.keyCode === 13) { sendButton.click(); } }); // 渲染接收到的消息 function renderMessage(message) { const messageElement = document.createElement('div'); messageElement.innerText = message; messageContainer.appendChild(messageElement); messageContainer.scrollTop = messageContainer.scrollHeight; } // 接收到消息后的处理逻辑... </script> </body> </html> ``` 上述代码中,我们将聊天窗口容器`#chatroom`设置为占据整个页面,并使用`display: flex;`实现了竖直方向的布局。消息容器`#message-container`使用`flex: 1;`将剩余空间填充,并设置了滚动条样式。输入框和发送按钮也进行了相应的布局设置。 通过JavaScript,我们可以监听发送按钮点击事件和输入框回车键事件,实现消息的发送和回车发送功能。此外,还提供了一个`renderMessage`函数用于渲染接收到的消息,并保持消息滚动条自动滚动到最底部。 该代码模板可以根据不同的页面大小自适应调整布局,并提供基本的聊天室交互功能。当接收到新消息时,滚动条也会相应地自动滚动到最底部,确保用户始终可以看到最新的消息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值