JavaScript TypeScript實(shí)現(xiàn)貪吃蛇游戲完整詳細(xì)流程
項(xiàng)目背景及簡(jiǎn)介
typescript系列到這篇文章正式進(jìn)入尾聲了,我們通過(guò)以上學(xué)習(xí)ts的知識(shí),想要熟悉的掌握必須要寫(xiě)一個(gè)小demo綜合運(yùn)用所學(xué)的知識(shí),這個(gè)項(xiàng)目的目的就是綜合ts所學(xué)知識(shí),實(shí)現(xiàn)面向?qū)ο蟮膶?shí)際開(kāi)發(fā)!
項(xiàng)目地址 : https://gitee.com/liuze_quan/ts-greedy-snake
多模塊需求分析
場(chǎng)景模塊需求
- 具有長(zhǎng)和寬的容器,容器內(nèi)分成蛇移動(dòng)和記分牌兩個(gè)板塊
- 蛇移動(dòng)的場(chǎng)景設(shè)置邊界線,邊界線一旦觸碰直接結(jié)束游戲
- 記分牌記錄蛇吃到食物的分?jǐn)?shù)以及等級(jí)
- 蛇吃到食物分?jǐn)?shù)漲一分,每漲一定分?jǐn)?shù)等級(jí)提高一級(jí)
- 等級(jí)設(shè)有上限
- 等級(jí)和蛇移動(dòng)速度有關(guān)
食物類模塊需求
- 在游戲開(kāi)始時(shí)候食物生成在隨機(jī)位置
- 當(dāng)蛇吃掉食物后食物會(huì)再次隨機(jī)出現(xiàn)(出現(xiàn)的位置不能與蛇身重合)
記分牌模塊需求
- 設(shè)置限制等級(jí)
- 可以提升等級(jí)
- 可以增加獲取的分?jǐn)?shù)
蛇類模塊需求
- 游戲開(kāi)始的時(shí)候只有一個(gè)方塊(蛇頭),隨后每吃掉一個(gè)食物則增加一節(jié)身體
- 當(dāng)游戲進(jìn)行過(guò)程中蛇頭碰到身體則結(jié)束游戲
- 蛇的前進(jìn)是持續(xù)的,不能停頓下來(lái),只能去改變方向
控制模塊需求
- 按下方向鍵開(kāi)始游戲
- 只能通過(guò)四個(gè)方向鍵改變蛇前進(jìn)的方向
- 判斷游戲是否結(jié)束,蛇是否吃到食物
- 控制分?jǐn)?shù)和等級(jí)是否相應(yīng)增長(zhǎng),食物是否刷新
項(xiàng)目搭建
ts轉(zhuǎn)譯為js代碼
我們需要?jiǎng)?chuàng)建tsconfig.json
文件,文件代碼如下:
{ "compilerOptions": { "module": "es6", "target": "es6", "strict": true, "noEmitOnError": true } }
package.json包配置文件
- 在這個(gè)小項(xiàng)目中我們需要webpack打包工具,所以我們要對(duì)
package.json
文件進(jìn)行一些配置。 - 選擇該項(xiàng)目在集成終端中打開(kāi)并輸入代碼
npm init -y
進(jìn)行項(xiàng)目初始化,這個(gè)時(shí)候會(huì)在你的項(xiàng)目中生成一個(gè)初步的package.json文件,然后我們進(jìn)一步完善 - 在集成終端中輸入指令
npm i -D webpack webpack-cli typescript ts-loader
用來(lái)下載相關(guān)依賴(如果可以看見(jiàn)package.json的depDependencies中更新了你下載的依賴表示下載成功)。i表示install下載的意思,-D意思是下載的作為依賴使用 - 繼續(xù)輸入指令npm i -D css-loader 等依賴,這些后面都有用
- 請(qǐng)注意上述代碼中scripts中的"build": "webpack"鍵值對(duì),這個(gè)設(shè)置說(shuō)明我們可以用npm run build的代碼來(lái)啟用webpack打包工具
{ "name": "part2", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "start": "webpack serve --open" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.18.9", "@babel/preset-env": "^7.18.9", "babel-loader": "^8.2.5", "clean-webpack-plugin": "^4.0.0", "core-js": "^3.24.0", "css-loader": "^6.7.1", "html-webpack-plugin": "^5.5.0", "less": "^4.1.3", "less-loader": "^11.0.0", "postcss": "^8.4.14", "postcss-loader": "^7.0.1", "postcss-preset-env": "^7.7.2", "style-loader": "^3.3.1", "ts-loader": "^9.3.1", "typescript": "^4.7.4", "webpack": "^5.74.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3" } }
webpack.config.js打包工具配置
webpack打包文件配置中,代碼注釋非常清楚,代碼如下:
//引入一個(gè)包 const path = require('path'); //引入html插件 const HTMLWebpackPlugin = require('html-webpack-plugin') const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // webpack 中所有的配置信息都寫(xiě)道嗎module.exports中 module.exports = { //指定入口文件 entry: './src/index.ts', //指定打包文件所在的目錄 output: { //指定打包文件的目錄 path: path.resolve(__dirname,'dist'), //打包后文件的名字 filename: "bundle.js", //告訴webpack不使用箭頭函數(shù) environment: { arrowFunction: false } }, mode: 'development', //指定webpack打包時(shí)要使用的模塊 module: { //指定要加載的規(guī)則 rules: [ { //test指定規(guī)則生成的文件 test: /\.ts$/, //要使用的loader use : [ //配置babel { // 指定加載器 loader: "babel-loader", //設(shè)置babel options: { //設(shè)置預(yù)定義的環(huán)境 presets:[ [ //指定環(huán)境的插件 "@babel/preset-env", //配置信息 { //要兼容的目標(biāo)瀏覽器 targets : { "chrome" : "101" }, //指定core.js的版本 "corejs":"3", //使用core.js的方式 usage 按需加載 "useBuiltIns": "usage" } ] ] } } , 'ts-loader' ], //要排除的文件 exclude: /node-modules/ }, //設(shè)置less文件的處理 { test : /\.less$/, use : [ "style-loader", "css-loader", //引入postcss { loader: "postcss-loader", options: { postcssOptions : { plugins: [ [ "postcss-preset-env", { browsers:'last 2 versions' } ] ] } } }, "less-loader" ] } ] }, //配置webpack插件 plugins: [ new CleanWebpackPlugin(), new HTMLWebpackPlugin({ // title: "自定義的title" template: "./src/index.html" }), ], //用來(lái)設(shè)置引用模塊 resolve: { extensions: ['.ts', '.js'] } }
到這里,我們要配置的文件都已經(jīng)配置結(jié)束,接下來(lái)正式進(jìn)入項(xiàng)目的開(kāi)發(fā)
項(xiàng)目結(jié)構(gòu)搭建
首先要進(jìn)行我們的html和css樣式搭建,搭建出來(lái)項(xiàng)目的頁(yè)面!
html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>貪吃蛇</title> </head> <body> <!--創(chuàng)建游戲的主容器--> <div id="main"> <!--設(shè)置游戲的舞臺(tái)--> <div id="stage"> <!--設(shè)置蛇--> <div id="snake"> <!--snake內(nèi)部的div 表示蛇的各部分--> <div></div> </div> <!--設(shè)置食物--> <div id="food"> <!--添加四個(gè)小div 來(lái)設(shè)置食物的樣式--> <div></div> <div></div> <div></div> <div></div> </div> </div> <!--設(shè)置游戲的積分牌--> <div id="score-panel"> <div> SCORE:<span id="score">0</span> </div> <div> level:<span id="level">1</span> </div> </div> </div> </body> </html>
css文件(這里使用的是less)
// 設(shè)置變量 @bg-color: #b7d4a8; //清除默認(rèn)樣式 * { margin: 0; padding: 0; //改變盒子模型的計(jì)算方式 box-sizing: border-box; } body{ font: bold 20px "Courier"; } //設(shè)置主窗口的樣式 #main{ width: 360px; height: 420px; // 設(shè)置背景顏色 background-color: @bg-color; // 設(shè)置居中 margin: 100px auto; border: 10px solid black; // 設(shè)置圓角 border-radius: 40px; // 開(kāi)啟彈性盒模型 display: flex; // 設(shè)置主軸的方向 flex-flow: column; // 設(shè)置側(cè)軸的對(duì)齊方式 align-items: center; // 設(shè)置主軸的對(duì)齊方式 justify-content: space-around; // 游戲舞臺(tái) #stage{ width: 304px; height: 304px; border: 2px solid black; // 開(kāi)啟相對(duì)定位 position: relative; // 設(shè)置蛇的樣式 #snake{ &>div{ width: 10px; height: 10px; background-color: #000; border: 1px solid @bg-color; // 開(kāi)啟絕對(duì)定位 position: absolute; } } // 設(shè)置食物 #food{ width: 10px; height: 10px; position: absolute; left: 40px; top: 100px; // 開(kāi)啟彈性盒 display: flex; // 設(shè)置橫軸為主軸,wrap表示會(huì)自動(dòng)換行 flex-flow: row wrap; // 設(shè)置主軸和側(cè)軸的空白空間分配到元素之間 justify-content: space-between; align-content: space-between; &>div{ width: 4px; height: 4px; background-color: black; // 使四個(gè)div旋轉(zhuǎn)45度 transform: rotate(45deg); } } } // 記分牌 #score-panel{ width: 300px; display: flex; // 設(shè)置主軸的對(duì)齊方式 justify-content: space-between; } }
項(xiàng)目頁(yè)面
多模塊搭建
在項(xiàng)目開(kāi)發(fā)中我們不可能把所有的代碼寫(xiě)到一個(gè)文件中,所以項(xiàng)目開(kāi)發(fā)必須會(huì)靈活運(yùn)用模塊化開(kāi)發(fā)思想,把實(shí)現(xiàn)的功能細(xì)化成一個(gè)個(gè)模塊。
完成Food(食物)類
//定義食物類 class Food { element : HTMLElement; constructor() { //獲取頁(yè)面中的food元素并賦給element this.element = document.getElementById('food')!; } //獲取食物x軸坐標(biāo)的方法 get X() { return this.element.offsetLeft; } //獲取食物y軸坐標(biāo)的方法 get Y() { return this.element.offsetTop; } //修改食物位置的方法 change() { //生成隨機(jī)位置 //食物的最小位置是0 最大是290 let left = Math.round(Math.random() * 29) * 10 let top = Math.round(Math.random() * 29) * 10 this.element.style.left = left + 'px'; this.element.style.top = top + 'px'; } } export default Food
代碼分析:
由于在配置typescript時(shí)我們?cè)O(shè)置了strict(嚴(yán)格)模式,因此
this.element = document.getElementById('food')!
中如果我們不加!
會(huì)讓編譯器不確定我們是否會(huì)獲取到food的dom元素而發(fā)生報(bào)錯(cuò)- 準(zhǔn)備了
get()
方法可以在控制模塊中隨時(shí)獲取food的具體定位 change()
方法為隨機(jī)刷新一次food的位置export default Food
代碼加在最后。為的是把food成為全局模塊暴露出去,這樣的話其他的模塊可以調(diào)用這個(gè)food模塊
完成ScorePanel(記分牌)類
//定義表示記分牌的類 class ScorePanel { score : number = 0; level : number = 1; scoreSpan :HTMLElement; levelEle : HTMLElement; //設(shè)置變量限制等級(jí) maxLevel : number; //設(shè)置一個(gè)變量多少分升級(jí) upScore : number; constructor(maxLevel : number = 10,Score : number = 10) { this.scoreSpan = document.getElementById('score')!; this.levelEle = document.getElementById('level')!; this.maxLevel = maxLevel this.upScore = Score } //設(shè)置加分的方法 AddScore() { this.score++; this.scoreSpan.innerHTML = this.score + '' if (this.score % this.upScore === 0 ) { this.AddLevel() } } //提升等級(jí) AddLevel() { if (this.level < this.maxLevel) { this.levelEle.innerHTML = ++this.level +'' } } } export default ScorePanel
代碼分析:
在記分牌模塊主要是兩種方法AddScore()
和AddLevel()
,分別用來(lái)控制分?jǐn)?shù)增加和等級(jí)提升,重點(diǎn)也有設(shè)置一個(gè)變量來(lái)限制等級(jí)和設(shè)置變量來(lái)判斷多少分上升一個(gè)等級(jí)
完成Snake(蛇)類
class Snake { //表示蛇頭的元素 head : HTMLElement; bodies : HTMLCollectionOf<HTMLElement>; //獲取蛇的容器 element : HTMLElement; constructor() { this.element = document.getElementById('snake')! this.head = document.querySelector('#snake>div') as HTMLElement; this.bodies = this.element.getElementsByTagName('div') } //獲取蛇的坐標(biāo) get X() { return this.head.offsetLeft; } get Y() { return this.head.offsetTop; } set X(value) { if(this.X === value) { return; } if(value < 0 || value > 290) { throw new Error('蛇撞墻了!') } //修改x時(shí),是在修改水平坐標(biāo),蛇在左右移動(dòng),蛇在向左移動(dòng)時(shí),不能向右掉頭 if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) { //如果發(fā)生的掉頭,讓蛇向反方向繼續(xù)移動(dòng) if(value > this.X) { //如果value大于舊值X,則說(shuō)明蛇在向右走,此時(shí)應(yīng)該發(fā)生掉頭,應(yīng)該使蛇繼續(xù)向左走 value = this.X - 10 } else { value = this.X + 10 } } this.moveBody() this.head.style.left = value +'px' this.checkHeadBody() } set Y(value) { if(this.Y === value) { return; } if(value < 0 || value > 290) { throw new Error('蛇撞墻了!') } //修改Y時(shí),是在修改水平坐標(biāo),蛇在上下移動(dòng),蛇在向上移動(dòng)時(shí),不能向下掉頭 if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) { //如果發(fā)生的掉頭,讓蛇向反方向繼續(xù)移動(dòng) if(value > this.Y) { //如果value大于舊值X,則說(shuō)明蛇在向右走,此時(shí)應(yīng)該發(fā)生掉頭,應(yīng)該使蛇繼續(xù)向左走 value = this.Y - 10 } else { value = this.Y + 10 } } this.moveBody() this.head.style.top = value + 'px' this.checkHeadBody() } //蛇增加身體的方法 addBody() { this.element.insertAdjacentHTML("beforeend","<div></div>") } //移動(dòng)身體方法 moveBody() { /* *將后邊的身體設(shè)置為前邊身體的位置 * 舉例子: * 第四節(jié) == 第三節(jié)的位置 * 第三節(jié) == 第二節(jié)的位置 * 第二節(jié) == 第一節(jié)的位置 * */ //遍歷 for(let i = this.bodies.length - 1;i>0;i--) { //獲取前邊身體位置 let x = (this.bodies[i-1] as HTMLElement).offsetLeft; let y = (this.bodies[i-1] as HTMLElement).offsetTop; //將值設(shè)置到當(dāng)前身體上 (this.bodies[i] as HTMLElement).style.left = x +'px'; (this.bodies[i] as HTMLElement).style.top = y +'px'; } } //檢查蛇頭是否撞到身體 checkHeadBody() { //獲取所有的身體,檢查其是否和蛇頭的坐標(biāo)發(fā)生重疊 for(let i =1;i<this.bodies.length;i++) { if(this.X === this.bodies[i].offsetLeft && this.Y === this.bodies[i].offsetTop) { //進(jìn)入判斷說(shuō)明蛇頭撞到了身體,游戲結(jié)束 throw new Error('撞到自己了') } } } } export default Snake
代碼分析:
首先它自身只添加了三個(gè)功能函數(shù)addbody,movebody和checkHeadBody
movebody
的實(shí)現(xiàn)邏輯非常的巧妙,根據(jù)從后往前的順序來(lái)確定位置,根據(jù)前一節(jié)的位置,從而讓后邊的位置替換到前一節(jié)的位置上,從而實(shí)現(xiàn)蛇可以移動(dòng)的邏輯。
為什么get,set,判斷蛇是否死亡機(jī)制以及之后的蛇移動(dòng)的代碼一定要寫(xiě)在constructor()函數(shù)中而不是寫(xiě)在外面?
在后面還有一個(gè)控制模塊中
首先利用get()方法獲得蛇頭坐標(biāo),當(dāng)蛇頭移動(dòng)一次以后,立刻刷新后的蛇頭坐標(biāo)反饋給蛇對(duì)象
蛇這個(gè)對(duì)象更新以后constructor代碼就會(huì)執(zhí)行一遍,執(zhí)行過(guò)程中首先蛇頭的坐標(biāo)用set()函數(shù)重新設(shè)置,然后蛇的movebody
函數(shù)就會(huì)執(zhí)行一次。最后對(duì)蛇進(jìn)行判斷死沒(méi)死。
這樣一次代碼就執(zhí)行完成啦。此時(shí)整條蛇都前進(jìn)了一次。然后我們通過(guò)定時(shí)器定個(gè)時(shí)間不斷讓蛇移動(dòng)就可以了。
完成GameControl(控制)類
import Food from "./food"; import Snake from "./Snake"; import ScorePanel from "./ScorePanel"; //游戲控制器,控制其他所有類 class GameControl { snake : Snake; food : Food; scorePanel : ScorePanel direction : string = ''; //創(chuàng)建一個(gè)變量來(lái)判斷游戲是否結(jié)束 isLive : boolean = true; constructor() { this.snake = new Snake() this.food = new Food() this.scorePanel = new ScorePanel() this.init() } //游戲的初始化,調(diào)用后游戲?qū)㈤_(kāi)始 init() { document.addEventListener('keydown',this.keydownHandler.bind(this)) //調(diào)用run this.run() } /*ArrowUp ArrowDown ArrowLeft ArrowRight */ //創(chuàng)建一個(gè)鍵盤(pán)按下的響應(yīng)函數(shù) keydownHandler(event: KeyboardEvent) { console.log(event.key) this.direction = event.key } //創(chuàng)建一個(gè)控制蛇移動(dòng)的方法 /* * 根據(jù)方向(this.direction)來(lái)使蛇位置發(fā)生改變 * * */ run() { let X = this.snake.X; let Y = this.snake.Y; //根據(jù)方向修改值 switch (this.direction) { case 'ArrowUp': case 'Up': Y-=10; break; case 'ArrowDown': case 'Down': Y+=10; break; case 'ArrowLeft': case 'Left': X -=10; break; case 'ArrowRight': case 'Right': X += 10; break; } (this.checkEat(X,Y)) try { //修改X和Y的值 this.snake.X = X; this.snake.Y = Y; }catch (e) { //進(jìn)入到catch出現(xiàn)異常 alert((e as any).message + '游戲結(jié)束了,老表!'); this.isLive = false; } this.isLive && setTimeout(this.run.bind(this),300 - (this.scorePanel.level-1)*30) } //定義方法檢查蛇是否吃到食物 checkEat(X:number,Y:number) { if (X === this.food.X && Y === this.food.Y) { //食物的位置要進(jìn)行重置 this.food.change() //分?jǐn)?shù)增加 this.scorePanel.AddScore() //蛇要增加一節(jié) this.snake.addBody() } } } export default GameControl
代碼分析:
我們?cè)O(shè)置控制類主要目的在于整合之前的三個(gè)類,從而在這個(gè)類中調(diào)用之前聲明的類,在該類中重點(diǎn)在于初始化游戲、控制蛇的移動(dòng)、檢查蛇是否吃到食物,這個(gè)類相當(dāng)于一個(gè)總開(kāi)關(guān)。
這里還有一個(gè)重點(diǎn)在于this指向問(wèn)題,這里使用了bind()
函數(shù),bind最直接的定義就是將this指向到當(dāng)前的對(duì)象。
完成index類(啟動(dòng)項(xiàng)目)
import './style/index.less' import GameControl from './modules/GameControl' new GameControl()
代碼分析:
大家都非常清楚,想要讓對(duì)象執(zhí)行,我們必須要進(jìn)行實(shí)例化,這里只用new
一下進(jìn)行調(diào)用即可,項(xiàng)目就可以執(zhí)行了
項(xiàng)目啟動(dòng)
最后我們打開(kāi)終端輸入npm start
或者npm run build
,項(xiàng)目就跑起來(lái)了,它可以自動(dòng)打開(kāi)瀏覽器進(jìn)行執(zhí)行
總結(jié)
學(xué)習(xí)完了typescript,其實(shí)最主要的在于運(yùn)用它實(shí)現(xiàn)面向?qū)ο蟮拈_(kāi)發(fā),我們?cè)谌粘i_(kāi)發(fā)中基本不會(huì)用到面向?qū)ο螅退鉫s6中涉及到類、接口等等,但是在實(shí)際中很少人去使用,面向?qū)ο蟮拈_(kāi)發(fā)中其實(shí)使得項(xiàng)目變得更加的嚴(yán)謹(jǐn)和合理化,我們?cè)跁?shū)寫(xiě)代碼的時(shí)候會(huì)更加的規(guī)范,ts的類型嚴(yán)格更加的使它方便大型項(xiàng)目開(kāi)發(fā)!
到此這篇關(guān)于JavaScript TypeScript實(shí)現(xiàn)貪吃蛇游戲完整詳細(xì)流程的文章就介紹到這了,更多相關(guān)JS TypeScript貪吃蛇內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript調(diào)用ajax獲取文本文件內(nèi)容實(shí)現(xiàn)代碼
這篇文章主要介紹了JavaScript調(diào)用ajax獲取文本文件內(nèi)容的方法,需要的朋友可以參考下2014-03-03JS組件中bootstrap multiselect兩大組件較量
這篇文章主要介紹了JS組件中bootstrap multiselect兩大組件,兩者之間的較量,優(yōu)缺點(diǎn)比較,感興趣的小伙伴們可以參考一下2016-01-01javascript function調(diào)用時(shí)的參數(shù)檢測(cè)常用辦法
js中并不直接支持類似c#的方法重載,所以只能變相的來(lái)解決,示意代碼:(利用了內(nèi)置屬性arguments)2010-02-02javascript簡(jiǎn)單性能問(wèn)題及學(xué)習(xí)筆記
最近在看一本書(shū):《高性能javaScript》,發(fā)現(xiàn)自己平時(shí)寫(xiě)js存在很多小細(xì)節(jié)上的問(wèn)題,雖然這些問(wèn)題不會(huì)導(dǎo)致程序運(yùn)行出錯(cuò),但是會(huì)導(dǎo)致界面加載變慢,用戶體驗(yàn)變差,那么我們就來(lái)細(xì)細(xì)數(shù)一下應(yīng)該注意的地方吧2014-02-02javascript 制作坦克大戰(zhàn)游戲初步 圖片與代碼
javascript 制作坦克大戰(zhàn)游戲初步 圖片與代碼...2007-11-11JavaScript數(shù)組扁平轉(zhuǎn)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn)
本文主要介紹了JavaScript數(shù)組扁平轉(zhuǎn)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Javascript實(shí)現(xiàn)簡(jiǎn)單二級(jí)下拉菜單實(shí)例
這篇文章主要介紹Javascript實(shí)現(xiàn)二級(jí)下拉菜單的具體過(guò)程,需要的朋友可以參考下2014-06-06在瀏覽器測(cè)試JavaScript的方法小結(jié)
測(cè)試JavaScript代碼是一件很痛苦的事情,很多情況下都是寫(xiě)好代碼不斷刷新測(cè)試,其實(shí)chrome瀏覽器的console下就很方便,這里就為大家簡(jiǎn)單分享一下2023-03-03js實(shí)現(xiàn)0ms延時(shí)定時(shí)器的幾種方式
本文主要介紹了js實(shí)現(xiàn)0ms延時(shí)定時(shí)器的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07javascript 讀取xml,寫(xiě)入xml 實(shí)現(xiàn)代碼
javascript xml讀取,寫(xiě)入xml 實(shí)現(xiàn)代碼2009-07-07