搜索
首页web前端js教程在nodejs+express环境中如何将搭建多人聊天室

在nodejs+express环境中如何将搭建多人聊天室

Jun 06, 2018 am 09:50 AM
expressnodejs聊天室

本篇文章给大家详细讲解了nodejs+express搭建一个简易的多人聊天室的详细步骤,有兴趣的朋友学习下。

前言

本文主要是笔者在学习node的时候,作为练手的一个小项目,花了几天空余时间,边码边写教程的一个过程。适用于对node理论知识看的多,实战少的同学,那么现在就让我们开始吧!

准备工作

新建一个文件夹 chatroom

在终端输入以下命令,按照步骤npm(没装过的去官网安装下node和npm)会自动给你生成一个package.json文件

安装express和socket.io

package.json文件如下:

//package.json
{
 "name": "chatroom",
 "version": "1.0.0",
 "description": "A simple chatroom",
 "main": "index.js",
 "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "repository": {
  "type": "git",
  "url": "git+https://github.com/ddvdd008/chatroom.git"
 },
 "keywords": [
  "chatroom",
  "nodejs",
  "express"
 ],
 "author": "ddvdd",
 "license": "ISC",
 "bugs": {
  "url": "https://github.com/ddvdd008/chatroom/issues"
 },
 "homepage": "https://github.com/ddvdd008/chatroom#readme"
}

安装express和socket.io

npm install express --save 
npm install socket.io --save

package.json自动新增依赖

"dependencies": {
 "express": "^4.16.2",
 "socket.io": "^2.0.4"
}

因为我们使用express框架写后端服务,用socket.io(Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,他会根据情况选择方法来进行通讯。)来对客户端和服务端建立一个持久链接,便于通讯。

到这里准备工作进行的差不多了,下面我们开始一步步实现。

搭建web服务器

express创建服务

学过node同学应该不陌生,利用http.createServer就能简单的创建一个服务器,这次我们利用express来创建服务。在项目根目录创建一个app.js。

/**
* Created by ddvdd on 2018-02-07.
*/
const express = require('express'); 
const app = express();    // 创建express实例,赋值给app。
const fs = require('fs');   // 这个是node的文件读取模块,用于读取文件
const path = require('path');  // 这是node的路径处理模块,可以格式化路径

app.listen(3000,()=>{    
 console.log("server running at 127.0.0.1:3000");  // 代表监听3000端口,然后执行回调函数在控制台输出。
});

/**
* app.get(): express中的一个中间件,用于匹配get请求,说的简单点就是node处理请求的路由,对于不同url请求,让对应的不同app.get()去处理
* '/': 它匹配get请求的根路由 '/'也就是 127.0.0.1:3000/就匹配到它了
* req带表浏览器的请求对象,res代表服务器的返回对象
*/
app.get('/',(req,res)=>{
 res.redirect('/chat.html');  // express的重定向函数。如果浏览器请求了根路由'/',浏览器就给他重定向到 '127.0.0.1:3000/chat.html'路由中
});


/**
* 这里匹配到的是/chat.html就是上面重定向到的路径。
*/
app.get('/chat.html',(req,res)=>{
 fs.readFile(path.join(__dirname,'./public/chat.html'),function(err,data){  //读取文件,readFile里传入的是文件路径和回调函数,这里用path.join()格式化了路径。
  if(err){
   console.error("读取chat.html发生错误",err);     //错误处理
   res.send('4 0 4');           //如果发生错误,向浏览器返回404
  } else {
   res.end(data);     //这里的data就是回调函数的参数,在readFile内部已经将读取的数据传递给了回调函数的data变量。
  }         //我们将data传到浏览器,就是把html文件传给浏览器
 })
});

你们看了以后会说,这express框架看来也没那么简便啊,一个最简单的发送单页面的方法跟node自带http.createServer没太大区别饿,也挺麻烦的。从目前来看确实如此,我这不是为了让你们容易理解嘛~ express提供了一个非常强大的中间件,帮我们托管静态资源文件,下面我们就来实现:

app.use('/',express.static(path.join(__dirname,'./public'))); //一句话就搞定。

代替原来的:

app.get('/chat.html',(req,res)=>{
 fs.readFile(path.join(__dirname,'./public/chat.html'),function(err,data){  
  if(err){
   console.error("读取chat.html发生错误",err);     
   res.send('4 0 4');           
  } else {
   res.end(data);     
  }         
 })
});

__dirname表示当前文件所在的绝对路径,所以我们使用path.join将app.js的绝对路径和public加起来就得到了public的绝对路径。用path.join是为了避免出现 ././public 这种奇怪的路径,express.static就帮我们托管了public文件夹中的静态资源。只要有 127.0.0.1:3000/XXX/AAA 的路径都会去public文件夹下找XXX文件夹下的AAA文件然后发送给浏览器。

现在再来看这段代码是不是简介了很多,具体了解app.use()干了什么的同学可以去这里

socket.io建立客户端和服务端的链接

创建完上面的服务后,我们需要把socket.io引用进来,让客户端和服务端建立长久链接。我们把app.js进行如下改造:

/**
* Created by ddvdd on 2018-02-07.
*/
const express = require('express'); 
const app = express();    // 创建express实例,赋值给app。
const server = require('http').Server(app); 
const io = require('socket.io')(server);  //将socket的监听加到app设置的模块里。这两句理解不了的可以去socket.io官网去看
const path = require('path');  // 这是node的路径处理模块,可以格式化路径

server.listen(3000,()=>{    
 console.log("server running at 127.0.0.1:3000");  // 代表监听3000端口,然后执行回调函数在控制台输出。 
}); 
...
...
app.use('/',express.static(path.join(__dirname,'./public')));  //一句话就搞定。 

/*socket*/ 
io.on('connection',(socket)=>{    //监听客户端的连接事件 
 
});

o.on表示监听某个事件,该事件一发生,就触发回调函数。'connection‘就是一个事件名,它已经定义好了,只要用户连接上就会触发。现在app.js基本已经完成,我们在根目录执行:

node app.js

>

现在访问http://127.0.0.1:3000/static/chat.html:

哎?啥也没有。。。那不废话!我们都没url请求对应的静态资源!

添加静态html

我们在项目根目录创建public文件夹,public文件夹里面新建chat.html文件:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
 <meta charset="UTF-8"> 
 <title>聊天室</title> 
</head> 
<body> 
这是我们的聊天室 
</body> 
</html>

现在我们刷新下页面,你看页面出现了:

>

到这里其实一个最简单的浏览器和web服务器协作的项目就已经完成,后面我们要不断完善页面,给服务器后端加业务功能来实现多人聊天室。

基本功能实现

登陆功能,我们需要一个用户名,(不需要密码),该用户名必须客户端服务器都有存储。每次传输信息基本都需要包括用户名,否则不知道是谁发的。

群聊功能,我们需要分辨信息来己方和对方

登陆功能实现

login页面重构

最基本的登陆界面由一个用户名输入框和登录按钮组成:

//chat.html
<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8"> 
<title>聊天室</title>
<style>
 *{
  margin:0;
  padding:0;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
 }
 .container{
  position: absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background-color: grey;
  padding: 50px;
 }
 .container .title{
  width:300px;
  margin: 0 auto;
  font-size: 30px;
  font-family: &#39;Franklin Gothic Medium&#39;;
  font-weight: bold;
  text-align: center;
  margin-bottom:50px;
 }
 .container .login-wrap{
  width:400px;
  padding: 20px;
  border: 1px solid #000;
  margin: 0 auto;
  text-align: center;
 }
 .login-wrap .user-ipt{
  width:360px;
  text-align: center;
  vertical-align: middle;
 }
 .login-wrap .login-button{
  width:60px;
  height:24px;
  line-height:20px;
  font-size: 14px;
  padding: 2px 0;
  border-radius: 5px;
  margin-top:10px;
 }
</style> 
</head> 
<body> 
 <p class="container">
  <p class="title">欢迎来到ddvdd聊天室</p>
  <p class="login-wrap">
   <p class="user-ipt">
    <span class="user-name">用户名:</span>
    <input id="name" class="name-ipt" type="text" />
   </p>
   <button id="loginbutton" class="login-button">登陆</button>
  </p>
 </p>
</body> 
</html>

简单的加点样式,静态页面就完成了,我们刷新下页面:

login页面交互

昨天下午写到一半。。。部门突然要去团建聚会,只能匆匆提交代码,草草了事。今天一大早来到公司继续给大家码

废话不多说进入正题,登陆这块交互,当用户访问服务器并且成功登陆算一个在线登陆人数,每登陆一个用户,服务器都会把用户信息存入一个数组中,保存在服务器,这里要注意一点,服务器会对用户登陆的用户名进行校验,校验结果会返回给客户端,客户端通过校验结果,改变当前页面是否进入聊天页面。

上面的服务器和客户端交互都是通过socket.io来实现通讯的,前端的业务交互我们这里就采用jquery来实现,在public文件夹下新建js文件夹,下载jquery-3.2.1.min.js、新建main.js。然后对chat.html引入需要的sdk:

<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/main.js"></script>
//socket.io官网要求这么引入
<script src="/socket.io/socket.io.js"></script>

引入完sdk,我们对main的js添加登录功能:

//main.js
/**
* Created by ddvdd on 2018-02-08.
*/
$(function(){
 const url = &#39;http://127.0.0.1:3000&#39;;
 let _username = &#39;&#39;;
 let _$inputname = $(&#39;#name&#39;);
 let _$loginButton = $(&#39;#loginbutton&#39;);

 let socket = io.connect(url);

 //设置用户名,当用户登录的时候触发
 let setUsername = () => {
  
  _username = _$inputname.val().trim(); //得到输入框中用户输入的用户名

  //判断用户名是否存在
  if(_username) {
   socket.emit(&#39;login&#39;,{username: _username}); //如果用户名存在,就代表可以登录了,我们就触发登录事件,就相当于告诉服务器我们要登录了
  }
  else{
   alert(&#39;请输入用户名!&#39;);
  }
 };
 
 
 
 /*前端事件*/
 _$loginButton.on(&#39;click&#39;,function (event) { //监听按钮的点击事件,如果点击,就说明用户要登录,就执行setUsername函数
  setUsername();
 });

 /*socket.io部分逻辑*/ 
 socket.on(&#39;loginResult&#39;,(data)=>{ 
  /** 
  * 如果服务器返回的用户名和刚刚发送的相同的话,就登录 
  * 否则说明有地方出问题了,拒绝登录 
  */ 
  if(data.code === 0) { 
   // 登陆成功,切换至聊天室页面 
  }
  else if(data.code ===1){ 
   alert(&#39;用户已登录!&#39;); 
  }
  else{
   alert(&#39;登录失败!&#39;);
  }
 }) 

});
//app.js
/**
* Created by ddvdd on 2018-02-07.
*/
const express = require(&#39;express&#39;); 
const app = express();    // 创建express实例,赋值给app。
const server = require(&#39;http&#39;).Server(app); 
const io = require(&#39;socket.io&#39;)(server);  //将socket的监听加到app设置的模块里。这两句理解不了的可以去socket.io官网去看
const path = require(&#39;path&#39;);  // 这是node的路径处理模块,可以格式化路径

const users = [];     //用来保存所有的用户信息 
let usersNum = 0;     //统计在线登录人数

server.listen(3000,()=>{    
 console.log("server running at 127.0.0.1:3000");  // 代表监听3000端口,然后执行回调函数在控制台输出。 
}); 


/**
* app.get(): express中的一个中间件,用于匹配get请求,说的简单点就是node处理请求的路由,对于不同url请求,让对应的不同app.get()去处理
* &#39;/&#39;: 它匹配get请求的根路由 &#39;/&#39;也就是 127.0.0.1:3000/就匹配到它了
* req带表浏览器的请求对象,res代表服务器的返回对象
*/
app.get(&#39;/&#39;,(req,res)=>{
 res.redirect(&#39;/static/chat.html&#39;);  // express的重定向函数。如果浏览器请求了根路由&#39;/&#39;,浏览器就给他重定向到 &#39;127.0.0.1:3000/chat.html&#39;路由中
});

/** 
* __dirname表示当前文件所在的绝对路径,所以我们使用path.join将app.js的绝对路径和public加起来就得到了public的绝对路径。 
* 用path.join是为了避免出现 ././public 这种奇怪的路径 
* express.static就帮我们托管了public文件夹中的静态资源。 
* 只要有 127.0.0.1:3000/XXX/AAA 的路径都会去public文件夹下找XXX文件夹下的AAA文件然后发送给浏览器。 
*/ 
app.use(&#39;/static&#39;,express.static(path.join(__dirname,&#39;./public&#39;)));  //一句话就搞定。 

/*socket*/ 
io.on(&#39;connection&#39;,(socket)=>{    //监听客户端的连接事件 
 
 socket.on(&#39;login&#39;,(data)=>{ 

  if(checkUserName(data)){
   socket.emit(&#39;loginResult&#39;,{code:1}); //code=1 用户已登录 
  }
  else{
   //将该用户的信息存进数组中 
   users.push({ 
    username: data.username, 
    message: [] 
   }); 
   socket.emit(&#39;loginResult&#39;,{code:0}); //code=0 用户登录成功
   usersNum = users.length; 
   console.log(`用户${data.username}登录成功,进入ddvdd聊天室,当前在线登录人数:${usersNum}`); 
  }
  
 }); 

 //断开连接后做的事情 
 socket.on(&#39;disconnect&#39;,()=>{   //注意,该事件不需要自定义触发器,系统会自动调用 
  usersNum = users.length; 
  console.log(`当前在线登录人数:${usersNum}`); 
 }); 
}); 
//校验用户是否已经登录
const checkUserName = (data) => {
 let isExist = false;
 users.map((user) => {
  if(user.username === data.username){
   isExist = true;
  }
 });
 return isExist;
}

上面代码大家需要了解以下几点:

  1. socket.on 表示监听事件,后面接一个回调函数用来接收emit发出事件传递过来的对象。

  2. socket.emit 用来触发事件,传递对象给on监听事件。

  3. 我们socket连接之后的监听触发事件都要写在io.on('connection')的回调里面,因为这些事件都是连接之后发生的,就算是断开连接的事件 disconnect 也是在连接事件中发生的,没有正在连接的状态,哪来的断开连接呢?

  4. 理解虽然服务器端只有app.js一个文件,但是不同的客户端连接后信息是不同的,所以我们必须要将一些公用的信息,比如说,储存所有登录用户的数组,所有用户发送的所有信息存储在外部,一定不能存储在connecion里

效果展示:

群聊功能实现

写完简单的登录功能,现在我们来写这项目最重要的功能群聊。首先我们先来处理下页面,因为功能简单,所以不单独建立html来显示聊天室,就直接写在login页面,通过class名称的变化来切换登录后,聊天室的显示。

聊天室页面重构

下面我们对chat.html进行整改:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
 <meta charset="UTF-8"> 
 <title>聊天室</title>
 <script src="js/jquery-3.2.1.min.js"></script> 
 <script src="js/main.js"></script> 
 <script src="/socket.io/socket.io.js"></script> 
 <style>
  *{
   margin:0;
   padding:0;
   box-sizing: border-box;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
  }
  .container{
   position: absolute;
   top:0;
   left:0;
   right:0;
   bottom:0;
   background-color: darkgrey;
   padding: 50px;
   overflow-y: scroll;
  }
  .container .title{
   margin: 0 auto;
   font-size: 30px;
   font-family: &#39;Franklin Gothic Medium&#39;;
   font-weight: bold;
   text-align: center;
   margin-bottom:20px;
  }
  .container .login-wrap{
   width:400px;
   padding: 20px;
   border: 1px solid #000;
   margin: 0 auto;
   text-align: center;
  }
  .login-wrap .user-ipt{
   width:360px;
   text-align: center;
   vertical-align: middle;
  }
  .login-wrap .login-button{
  width:60px;
  height:24px;
  line-height:20px;
  font-size: 14px;
  padding: 2px 0;
  border-radius: 5px;
  margin-top:10px;
  }
  .chat-wrap .chat-content{
   width:100%;
   height:600px;
   background-color: whitesmoke;
   padding:10px;
  }
  .chat-wrap .send-wrap{
   margin-top: 20px;
  }
  .message-ipt{
   width: 200px;
   height: 100px;
   padding: 0 5px;
   vertical-align: bottom;
  }
  .chat-content p{
   display: block;
   margin-bottom: 10px;
  }
  .chat-content p .msg{
   display: inline-block;
   padding: 8px 11px;
   border-radius:6px;
  }
  .chat-content .self-message .msg{
   background-color:#d0e7ff;
   border: 1px solid #c9dfff;
  }
  .chat-content .other-message .msg{
   background-color:white;
   border: 1px solid #eee;
  }
  .chat-content .self-message{
   text-align:right;
  }
  .chat-content .other-message{
   text-align-last:left;
  }
 </style> 
</head> 
<body> 
 <p class="container">
  <p id="loginbox" class="login-wrap">
   <p class="title">登录</p>
   <p class="user-ipt">
    <span class="user-name">用户名:</span>
    <input id="name" class="name-ipt" type="text" />
   </p>
   <button id="loginbutton" class="login-button">登录</button>
  </p>
  <p id="chatbox" class="chat-wrap" style="display:none">
   <p id="content" class="chat-content">
    <!-- 聊天内容 -->
   </p>
   <p class="send-wrap">
    <textarea rows="3" cols="20" id="chatmessage" class="message-ipt" type="textarea" placeholder="请输入要发送的信息内容"></textarea>
   </p>
  </p>
 </p>
</body> 
</html>

新增chatbox容器来作为聊天室,里面有一个群聊的聊天框,和一个发送消息的文本框。通过上面loginResult回调,对loginbox进行隐藏,显示chatbox:

//显示聊天室界面
let showChatRoom = () => {
 /** 
  * 1.隐藏登录框,取消它绑定的事件 
  * 2.显示聊天界面 
  */ 
 $(&#39;#loginbox&#39;).hide(&#39;slow&#39;);
 _$loginButton.off(&#39;click&#39;);
 /** 
 * 显示聊天界面,并显示一行文字,欢迎用户 
 */
 $(`<p class="title">欢迎${_username}来到ddvdd聊天室</p>`).insertBefore($("#content")); 
 $("#chatbox").show(&#39;slow&#39;);
}

消息事件发送监听机制

聊天一定是客户端触发的,所以发送信息是客户端触发,服务器监听。

服务器监听到发送信息的事件后会存储信息,然后触发发送信息成功事件广播给所有客户端,将信息传给所有客

户端。

发送消息sendMessage事件

//main.js
//发送消息
let sendMessage = function () { 
 /** 
  * 得到输入框的聊天信息,如果不为空,就触发sendMessage 
  * 将信息和用户名发送过去 
  */ 
 let _message = _$chattextarea.val(); 
 
 if(_message) { 
  socket.emit(&#39;sendMessage&#39;,{username: _username, message: _message}); 
 }
 else{
  alert(&#39;请输入发送消息!&#39;);
 } 
}; 
...
/*聊天事件*/ 
_$chattextarea.on(&#39;keyup&#39;,function (event) { 
 if(event.keyCode === 13) { 
  sendMessage(); 
  _$chattextarea.val(&#39;&#39;); 
 } 
});

服务器端监听sendMessage事件

//app.js
/** 
 * 监听sendMessage,我们得到客户端传过来的data里的message,并存起来。 
 */ 
socket.on(&#39;sendMessage&#39;,(data)=>{ 
 for(let _user of users) { 
  if(_user.username === data.username) { 
   _user.message.push(data.message); 
   //信息存储之后触发receiveMessage将信息发给所有浏览器-广播事件 
   io.emit(&#39;receiveMessage&#39;,data); 
   break; 
  } 
 } 
});

我们是遍历服务器端的用户数组,找到该用户,将发送的信息存起来,然后触发receiveMessage事件广播到所有浏览器,sendMessage是写在connection里,login之外的,为什么这么做大家一定要理解,发送消息是连接时候做的事情,而不是登录时做的事情。

注意的是,我使用的是io.emit,他是真正的广播到所有浏览器,socket.broadcast.emit则不会广播到自己的浏览器。

客户端监听receiveMessage事件

//main.js
socket.on(&#39;receiveMessage&#39;,(data)=>{ 
 /** 
  * 
  * 监听服务器广播的消息
  */ 
 showMessage(data);
}) 
//显示消息
let showMessage = function (data) { 
 //先判断这个消息是不是自己发出的,然后再以不同的样式显示 
 if(data.username === _username){ 
  $("#content").append(`<p class=&#39;self-message&#39;><span class=&#39;msg&#39;>${data.message}</span><span class=&#39;name&#39;> :${data.username}</span></p>`); 
 }else { 
  $("#content").append(`<p class=&#39;other-message&#39;><span class=&#39;name&#39;>${data.username}: </span><span class=&#39;msg&#39;>${data.message}</span></p>`); 
 } 
};

写到这边,我们的聊天室基本功能已经完成了,来看看效果吧!打开三个浏览器,分别登录老大、老二、老三,发一句“大噶好~,我是渣渣辉!”。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用Node.js实现压缩和解压缩功能

使用tween.js实现缓动补间动画算法

详细讲解React中的refs(详细教程)

以上是在nodejs+express环境中如何将搭建多人聊天室的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python vs. JavaScript:性能和效率注意事项Python vs. JavaScript:性能和效率注意事项Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript的起源:探索其实施语言JavaScript的起源:探索其实施语言Apr 29, 2025 am 12:51 AM

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

幕后:什么语言能力JavaScript?幕后:什么语言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来:趋势和预测Python和JavaScript的未来:趋势和预测Apr 27, 2025 am 12:21 AM

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

Python vs. JavaScript:开发环境和工具Python vs. JavaScript:开发环境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

JavaScript是用C编写的吗?检查证据JavaScript是用C编写的吗?检查证据Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。

JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!