首页 文章 精选 留言 我的

精选列表

搜索[JavaScript],共9119篇文章
优秀的个人博客,低调大师

GitHub重磅年度报告:JavaScript最热,中国开发者贡献稳居第二

GitHub大动作,开发者福利:重磅推出GitHub Actions! 在昨日举行的GitHub Universe 2018开发者大会上,GitHub发布了一款重量级产品:GitHub Actions,可直接运行部分代码的产品,彻底改变GitHub的使用方式。 正如平台主管Sam Lambert所说:“这将是GitHub史上最大的转变!” 除了发布GitHub Actions等新产品外,GitHub还公布了2018年年度报告。 GitHub Actions:开源、社区支持的平台 GitHub认为,作为一个开发者,大部分时间和经历应该只放在一件事情上,那就是代码。 在过去,开发者因配置工作流程,或使用不灵活的工具,浪费了大量的时间。而这正式GitHub要解决的问题。 现在,GitHub给开发者们提供了一种自动管理代码的工具,包括测试和技术支持。“

优秀的个人博客,低调大师

【JavaScript游戏开发】使用HTML5 canvas开发的网页版中国象棋项目

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81905647 //V1.0 : 实现棋子的布局,画布及游戏场景的初始化 //V2.0 : 实现棋子的颜色改变 //V3.0 :实现所有象棋的走棋规则 //V4.0 : 实现所有棋子的吃子功能 完整的项目源码已经开源:https://github.com/xiugangzhang/ChineseChess 项目在线预览地址: http://htmlpreview.github.io/?https://github.com/xiugangzhang/ChineseChess/blob/master/ChineseChess.html 目前就实现了上面的几个功能,最近也么时间再弄了,需要的朋友可以自己下载下来继续开发哈! 主要特点: 1.无任何插件和第三方库,纯原生js实现 2.没使用任何素材,棋盘和棋子都是由canvas画布绘制 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <canvas id="myCanvas" width="600px" height="660px"> </canvas> <script> //V1.0 : 实现棋子的布局,画布及游戏场景的初始化 //V2.0 : 实现棋子的颜色改变 //V3.0 :实现所有象棋的走棋规则 //V4.0 : 实现所有棋子的吃子功能 var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); /** * 棋子对象 * @param x * @param y * @param color * @constructor */ function Chess(x, y, color, type) { this.x = x; this.y = y; this.color = color; this.type = type; // 记录颜色 this.chessColor = color; // 是否死掉 this.isDead = false; } // 成员函数 Chess.prototype = { _getChessText: function () { switch (this.type) { case "CHE": return "车"; case "MA": return "马"; case "PAO": return "炮"; case "BING": return "兵"; case "JIANG": return "将"; case "SHI": return "士"; case "XIANG": return "相"; } return "错误"; } } /** * 游戏场景 * @constructor */ function Game() { // 存放当前棋盘上所有的棋子 this._chesses = []; //初始位置 this._initX = 60; this._initY = 60; // 判断鼠标是否点击有棋子 this._selectedChess = null; this._initCount = 0; } Game.prototype = { // 场景的初始化 execute: function () { this._initChesses(); this._start(); }, _initChesses: function () { // 绘制棋子(初始位置) // 总共需要绘制32颗棋子 // 红色棋子 var redChess; for (var i = 0; i < 4; i++) { for (var j = 0; j < 9; j++) { if ((i == 0 && j == 0) || (j == 8 && i == 0)) { // 把棋子的颜色传进去 redChess = new Chess(j, i, "red", "CHE"); this._chesses.push(redChess); } else if ((j == 1 && i == 0) || (j == 7 && i == 0 )) { redChess = new Chess(j, i, "red", "MA"); this._chesses.push(redChess); } else if ((j == 2 && i == 0) || (j == 6 && i == 0)) { redChess = new Chess(j, i, "red", "XIANG"); this._chesses.push(redChess); } else if ((j == 3 && i == 0) || (j == 5 && i == 0)) { redChess = new Chess(j, i, "red", "SHI"); this._chesses.push(redChess); } else if ((j == 4 && i == 0)) { redChess = new Chess(j, i, "red", "JIANG"); this._chesses.push(redChess); } else if ((j == 1 && i == 2) || (j == 7 && i == 2)) { redChess = new Chess(j, i, "red", "PAO"); this._chesses.push(redChess); } else if ((j == 0 && i == 3) || (j == 2 && i == 3) || (j == 4 && i == 3) || (j == 6 && i == 3) || (j == 8 && i == 3)) { redChess = new Chess(j, i, "red", "BING"); this._chesses.push(redChess); } } } // 绘制黑色棋子 var blackChess; for (var i = 6; i < 10; i++) { for (var j = 0; j < 10; j++) { if ((j == 0 && i == 9) || (j == 8 && i == 9)) { blackChess = new Chess(j, i, "black", "CHE"); this._chesses.push(blackChess); } else if ((j == 1 && i == 9) || (j == 7 && i == 9)) { blackChess = new Chess(j, i, "black", "MA"); this._chesses.push(blackChess); } else if ((j == 2 && i == 9) || (j == 6 && i == 9)) { blackChess = new Chess(j, i, "black", "XIANG"); this._chesses.push(blackChess); } else if ((j == 3 && i == 9) || (j == 5 && i == 9)) { blackChess = new Chess(j, i, "black", "SHI"); this._chesses.push(blackChess); } else if (j == 4 && i == 9) { blackChess = new Chess(j, i, "black", "JIANG"); this._chesses.push(blackChess); } else if ((j == 1 && i == 7) || (j == 7 && i == 7)) { blackChess = new Chess(j, i, "black", "PAO"); this._chesses.push(blackChess); } else if ((j == 0 && i == 6) || (j == 2 && i == 6) || (j == 4 && i == 6) || (j == 6 && i == 6) || (j == 8 && (i == 6))) { blackChess = new Chess(j, i, "black", "BING"); this._chesses.push(blackChess); } } } //console.log(redChess); //console.log(blackChess); console.log(this._chesses); }, /** * 绘制棋子 车马相士将 * @private */ _drawChesses: function () { var isDeadChess = null; // 根据游戏中棋子的数目来绘制棋子 // 游戏中的棋子始终是32颗, 因此只能根据棋子是否存活来决定是否绘制这个棋子(原来的位置还是有棋子, 这是让他隐藏起来) for (var i = 0; i < this._chesses.length; i++) { var chess = this._chesses[i]; // 原来的位置还是有棋子, 这是让他隐藏起来 if (!chess.isDead) { // 只有当这个棋子的属性isDead = false; 才绘制这个棋子 // 根据棋子的属性来绘制 context.fillStyle = "#C78843"; context.beginPath(); // 绘制棋子(注意要把棋子的初始位置复位) context.arc(chess.x * 60 + this._initX, chess.y * 60 + this._initY, 25, 0, Math.PI * 2, true); context.closePath(); context.fill(); // 绘制文本 if (chess.color == "red") { context.fillStyle = 'red'; } if (chess.color == "black") { context.fillStyle = 'black'; } if (chess.color == "blue") { context.fillStyle = 'blue'; } context.font = '43px 华文新魏'; context.fillText(chess._getChessText(), chess.x * 60 + this._initX - 22, chess.y * 60 + this._initY + 10); } else { isDeadChess = chess; } } // 有棋子被吃了,就重新开始 //this._selectedChess = null; if (this._initCount == 0) { //console.log(chess.x+","+chess.y+","+chess.type+"已经隐藏"); } }, _drawChessboard: function () { context.strokeStyle = "black"; // 绘制棋盘外边界 context.lineWidth = 3; context.beginPath(); context.moveTo(0, 0); context.lineTo(600, 0); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(0, 0); context.lineTo(0, 660); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(600, 0); context.lineTo(600, 660); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(0, 660); context.lineTo(660, 660); context.closePath(); context.stroke(); // 内部的外边界 context.beginPath(); context.moveTo(40, 40); context.lineTo(40, 620); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(40, 40); context.lineTo(560, 40); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(560, 40); context.lineTo(560, 620); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(560, 620); context.lineTo(40, 620); context.closePath(); context.stroke(); //棋盘横线 context.lineWidth = 1; for (var i = 1; i < 11; i++) { context.beginPath(); context.moveTo(60, 60 * i); context.lineTo(540, 60 * i); context.closePath(); context.stroke(); } // 棋盘纵线 for (var i = 1; i < 10; i++) { context.beginPath(); context.moveTo(i * 60, 60); context.lineTo(i * 60, 300); context.closePath(); context.stroke(); } for (var i = 1; i < 10; i++) { context.beginPath(); context.moveTo(i * 60, 360); context.lineTo(i * 60, 600); context.closePath(); context.stroke(); } context.beginPath(); context.moveTo(60, 300); context.lineTo(60, 360); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(540, 300); context.lineTo(540, 360); context.closePath(); context.stroke(); // 棋盘斜线 context.beginPath(); context.moveTo(240, 60); context.lineTo(360, 180); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(360, 60); context.lineTo(240, 180); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(240, 480); context.lineTo(360, 600); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(360, 480); context.lineTo(240, 600); context.closePath(); context.stroke(); // 绘制炮的位置(左上) context.beginPath(); context.moveTo(115, 160); context.lineTo(115, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 175); context.lineTo(100, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 160); context.lineTo(125, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 175); context.lineTo(140, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 185); context.lineTo(115, 200); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 185); context.lineTo(100, 185); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 185); context.lineTo(125, 200); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 185); context.lineTo(140, 185); context.closePath(); context.stroke(); // 右上 context.beginPath(); context.moveTo(475, 175); context.lineTo(460, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 175); context.lineTo(475, 160); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 160); context.lineTo(485, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 175); context.lineTo(500, 175); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 185); context.lineTo(485, 200); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 185); context.lineTo(500, 185); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 185); context.lineTo(475, 200); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 185); context.lineTo(460, 185); context.closePath(); context.stroke(); // 左下 context.beginPath(); context.moveTo(115, 485); context.lineTo(115, 500); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 485); context.lineTo(100, 485); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 475); context.lineTo(100, 475); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(115, 475); context.lineTo(115, 460); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 475); context.lineTo(140, 475); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 475); context.lineTo(125, 460); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 485); context.lineTo(140, 485); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(125, 485); context.lineTo(125, 500); context.closePath(); context.stroke(); // 右下 context.beginPath(); context.moveTo(475, 485); context.lineTo(475, 500); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 485); context.lineTo(460, 485); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 475); context.lineTo(475, 460); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(475, 475); context.lineTo(460, 475); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 475); context.lineTo(500, 475); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 475); context.lineTo(485, 460); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 485); context.lineTo(500, 485); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(485, 485); context.lineTo(485, 500); context.closePath(); context.stroke(); }, _drawnTitle: function () { //context.clearRect(0, 0, canvas.width, canvas.height); context.fillStyle = 'black'; context.font = '40px 华文新魏'; context.fillText("楚河", 130, 340); context.fillText("汉界", 380, 340); }, _start: function () { // 监听事件, 把触发这个事件的对象也传递过去 document.addEventListener("click", this._mouseClick.bind(this)); var that = this; // 利用定时器不断重绘canvas var timer = setInterval(function () { that._draw(); }, 30); }, _draw: function () { context.clearRect(0, 0, canvas.width, canvas.height); this._drawChessboard(); // 绘制棋子 this._drawChesses(); this._drawnTitle(); }, _mouseClick: function (e) { // 把棋盘归一化 var px = e.clientX - this._initX + 25; var py = e.clientY - this._initY + 25; //console.log(px + " "+py); // 当前鼠标点击棋盘的位置 var x = parseInt(px / 60); var y = parseInt(py / 60); if (x > 8 || x < 0 || y > 9 || y < 0 || px < 0) { return; } console.log(this._selectedChess); // 之前没有选中棋子(一直点击的是空白位置) if (this._selectedChess == null) { //如果当前鼠标点击的位置有棋子,就是选中了棋子 for (var i = 0; i < this._chesses.length; i++) { var chess = this._chesses[i]; // 每次拿出来棋子都要看一下这个棋子是不是还活着, 已经死了的棋子不处理 if (!chess.isDead) { if (x == chess.x && y == chess.y) { // 如果有棋子 this._selectedChess = chess; this._selectedChess.color = "blue"; break; } else { // 没有棋子 //alert("没有棋子"); //break; } } } } else { var color = this._selectedChess.chessColor; var srcX = this._selectedChess.x; var srcY = this._selectedChess.y; var destX = x; var destY = y; this._canKill(srcX, srcY, destX, destY); // 如果已经有了选择的棋子,就看这一次点击的位置有没有棋子 /*var chess = this._getChess(x, y); if (chess){ // 如果这个位置有棋子 console.log("有棋子"); if (chess.chessColor == this._selectedChess.chessColor){ // 如果这两个棋子的颜色相同 alert("请不要自相残杀!"); //同一个棋子点击了两下就恢复初始状态 //this._selectedChess = null; this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } else { // 如果颜色不相同 // 首先看一下这个棋子能不能移动 var type = this._selectedChess.type; var srcX = this._selectedChess.x; var srcY = this._selectedChess.y; var destX = x; var destY = y; var color = this._selectedChess.chessColor; // 我们先来判断能不能移动棋子, 然后再来判断能不能吃子 switch (type) { case "CHE": if (this._canMoveChe(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "MA": if (this._canMoveMa(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "XIANG": if (this._canMoveXiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "SHI": if (this._canMoveShi(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "JIANG": if (this._canMoveJiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "PAO": if (this._canMovePao(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } case "BING": if (this._canMoveBing(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; } } } // 已经有选择的棋子 for (var i = 0; i < this._chesses.length; i++) { var chess = this._chesses[i]; // 只处理没有死掉的棋子 if (x == chess.x && y == chess.y) { // 这次点击的位置如果有棋子,就看有没有死 if (!chess.isDead) { // 第一次有棋子, 第二次也有棋子 // 判断两次点击的棋子颜色是不是相同 if (chess.chessColor == this._selectedChess.chessColor) { // 两次点击的颜色都相同 if ((chess.type == this._selectedChess.type) && (chess.x == this._selectedChess.x) && (chess.y == this._selectedChess.y)) { // 颜色坐标和属性都相同(同一个棋子) alert("你选择的是同一个棋子"); //同一个棋子点击了两下就恢复初始状态 //this._selectedChess = null; this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; break; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能自相残杀!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; break; } } else { // 两次点击的颜色不相同 alert(this._selectedChess.chessColor + "可以吃" + chess.chessColor); var type = this._selectedChess.type; // 在我吃棋子的时候我先去判断选择的棋子能不能移动到目标的位置 switch (type) { case "CHE": break; case "MA": break; case "XIANG": break; case "SHI": break; case "JIANG": if (this._canMoveJiang(x, y)) { // 目标棋子消失,我方棋子补上去 chess.isDead = true; // 补上去(这里修改的其实是之前那颗棋子的引用) this._selectedChess.x = chess.x; this._selectedChess.y = chess.y; // 颜色恢复 this._selectedChess.color = this._selectedChess.chessColor; // 吃完棋子之后, 就恢复到初始状态 this._selectedChess = null; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("吃法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; } break; case "PAO": case "BING": break; } // 目标棋子消失,我方棋子补上去 chess.isDead = true; // 补上去(这里修改的其实是之前那颗棋子的引用) this._selectedChess.x = chess.x; this._selectedChess.y = chess.y; // 颜色恢复 this._selectedChess.color = this._selectedChess.chessColor; // 吃完棋子之后, 就恢复到初始状态 this._selectedChess = null; break; } } else { // 第一次有棋子, 第二次没有棋子 //alert("移动棋子"); //break; // 棋子已经死了的话,就不考虑 console.log("移动棋子"); } } else { // 第二次点击的位置上面没有棋子 console.log("移动棋子222"); var type = this._selectedChess.type; var srcX = this._selectedChess.x; var srcY = this._selectedChess.y; var destX = x; var destY = y; var color = this._selectedChess.chessColor; // 我们先来判断能不能移动棋子, 然后再来判断能不能吃子 switch (type) { case "CHE": if (this._canMoveChe(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "MA": if (this._canMoveMa(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "XIANG": if (this._canMoveXiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "SHI": if (this._canMoveShi(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "JIANG": if (this._canMoveJiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "PAO": if (this._canMovePao(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } case "BING": if (this._canMoveBing(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; } } }*/ //alert("1212"); } }, _isChessSelected: function () { }, _canMoveChe: function (color, srcX, srcY, destX, destY) { // 获得点击坐标处的所有xy上面的棋子状态 var allCanMovePoint = this._getXAndYChesss(srcX, srcY); // 想办法获得横纵坐标上面一旦有棋子之间的坐标 // 这几个数组主要用于存储我点击的位置上下左右四个方向第一次出现棋子到我现在这个棋子之间的棋子状态 var rightChess = this._getRightChesses(srcX, srcY); var leftChess = this._getLeftChesses(srcX, srcY); var upChess = this._getUpChesses(srcX, srcY); var downChess = this._getDownChesses(srcX, srcY); // 开始实现移动车的规则. for (var i = 0; i < allCanMovePoint.length; i++) { var point = allCanMovePoint[i]; if (destX == point.x && destY == point.y) { // 如果我当前要移动的点在我的这个点集合中 if (!point.tag) { //而且这个位置没有棋子 // 开始进一步限定移动的范围 // 上 if (destY < srcY) { for (var j = 0; j < upChess.length; j++) { // 取出可以向上移动的所有棋子的位置 var chess = upChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 下 if (destY > srcY) { for (var j = 0; j < downChess.length; j++) { var chess = downChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 左 if (destX < srcX) { for (var j = 0; j < leftChess.length; j++) { var chess = leftChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 右 if (destX > srcX) { for (var j = 0; j < rightChess.length; j++) { var chess = rightChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } } return false; } else{ //如果有棋子 // 看下这个棋子的颜色 var chessColor = point.chessColor; if (chessColor != ""){ // 这个位置有棋子 var srcChess = this._getChess(srcX, srcY); var killChess = this._getChess(destX, destY); if (chessColor != srcChess.chessColor){ // 杀死的棋子消失 killChess.isDead = true; srcChess.x = destX; srcChess.y = destY; // 可以移动 return true; } } } } } return false; }, _canMoveMa: function (color, srcX, srcY, destX, destY) { // 获得可以移动的位置点 var maCanMovePoint = []; // 是否可以真正移动的标记 var isMaCanMove = false; // 找到马周围的可以移动的8个点 var tag = false; // 默认没有棋子 for (var i = srcX - 2; i <= srcX + 2; i++) { for (var j = srcY - 2; j <= srcY + 2; j++) { // 只存储在棋盘里面的棋子 if (i >= 0 && i <= 8 && j >= 0 && j <= 9) { // 保存之前还有看一下以下几个问题(向左) if ((destX == srcX - 2 && destY == srcY - 1) || (destX == srcX - 2 && destY == srcY + 1)){ var chess = this._getChess(srcX-1, srcY); if (!chess){ isMaCanMove = true; } } // 向上 if ((destX == srcX - 1 && destY == srcY-2) || (destX == srcX+1 && destY == srcY-2)){ var chess = this._getChess(srcX, srcY-1); if (!chess){ isMaCanMove = true; } } // 向右 if ((destX == srcX +2 && destY == srcY-1) || (destX == srcX+2 && destY == srcY+1)){ var chess = this._getChess(srcX+1, srcY); if (!chess){ isMaCanMove = true; } } // 向下 if ((destX == srcX -1 && destY == srcY+2) || (destX == srcX+1 && destY == srcY+2)){ var chess = this._getChess(srcX, srcY+1); if (!chess){ isMaCanMove = true; } } if ((srcX - 2 == i && srcY - 1 == j) || (srcX - 2 == i && srcY + 1 == j) || (srcX - 1 == i && srcY - 2 == j) || (srcX - 1 == i && srcY + 2 == j) || (srcX + 1 == i && srcY - 2 == j) || (srcX + 1 == i && srcY + 2 == j) || (srcX + 2 == i && srcY - 1 == j) || (srcX + 2 == i && srcY + 1 == j)) { var chess = this._getChess(i, j); if (chess) { tag = true; } else { tag = false; } // 保存点 maCanMovePoint.push({ x: i, y: j, tag: tag, isCanMove : isMaCanMove }); } } } } // 拿到这个集合, 然后遍历 for (var i = 0; i<maCanMovePoint.length; i++){ var point = maCanMovePoint[i]; //看我当前点击的位置有没有在这些点集合中 if (destX == point.x && destY == point.y){ //如果在的话 if (!point.tag){ // 而且这个位置没有棋子 if (point.isCanMove){ return true; } } } } return false; }, _canMoveXiang: function (color, srcX, srcY, destX, destY) { var xiangCanMovePoint = []; if (color == "black") { xiangCanMovePoint = [{x: 0, y: 7}, {x: 2, y: 5}, {x: 2, y: 9}, {x: 4, y: 7}, {x: 6, y: 5}, { x: 6, y: 9 }, {x: 8, y: 7}]; } else { xiangCanMovePoint = [{x: 0, y: 2}, {x: 2, y: 0}, {x: 2, y: 4}, {x: 4, y: 2}, {x: 6, y: 0}, { x: 6, y: 4 }, {x: 8, y: 2}]; } // 象的移动不能超过2格子 if (Math.abs(srcX - destX) == 2 || Math.abs(srcY - destY) == 2) { // 再看这个田字状的中心有没有棋子 var centerX = (destX + srcX) / 2; var centerY = (destY + srcY) / 2; console.log("cebter:" + centerX + "," + centerY); if (this._getChess(centerX, centerY)) { // 有棋子 return false; } else { for (var i = 0; i < xiangCanMovePoint.length; i++) { var point = xiangCanMovePoint[i]; if (destX == point.x && destY == point.y) { // 再去看这个位置有没有棋子 var chess = this._getChess(destX, destY); if (chess && chess.chessColor == color) { // 有棋子 return false; } else { return true; } } } } } return false; }, _canMoveShi: function (color, srcX, srcY, destX, destY) { var shiCanMovePoint = []; if (color == "black") { shiCanMovePoint = [{x: 3, y: 7}, {x: 3, y: 9}, {x: 5, y: 7}, {x: 5, y: 9}, {x: 4, y: 8}]; } else { shiCanMovePoint = [{x: 3, y: 0}, {x: 3, y: 2}, {x: 5, y: 0}, {x: 5, y: 2}, {x: 4, y: 1}]; } // 一进来看下是不是跨格子移动 if (Math.abs(srcX - destX) == 1 || Math.abs(srcY - destY) == 1) { for (var i = 0; i < shiCanMovePoint.length; i++) { var point = shiCanMovePoint[i]; if (destX == point.x && destY == point.y) { //再去看这个位置有没有棋子 var chess = this._getChess(destX, destY); // 如果这里有棋子,而且是自己的棋子,就不能移动 if (chess && chess.chessColor == color) { // 有棋子 return false; } else { // 没有棋子 return true; } } } } }, _canMoveJiang: function (color, srcX, srcY, destX, destY) { var jingCanMovePoint = []; // 先看下是什么颜色 if (color == "black") { // 黑色棋子 jingCanMovePoint = [{x: 3, y: 7}, {x: 3, y: 8}, {x: 3, y: 9}, {x: 4, y: 7}, { x: 4, y: 8 }, {x: 4, y: 9}, {x: 5, y: 7}, {x: 5, y: 8}, {x: 5, y: 9}]; } else { // 红色棋子 jingCanMovePoint = [{x: 3, y: 0}, {x: 3, y: 1}, {x: 3, y: 2}, {x: 4, y: 0}, { x: 4, y: 1 }, {x: 4, y: 2}, {x: 5, y: 0}, {x: 5, y: 1}, {x: 5, y: 2}]; } //一进来就先判断是不是跨格子移动 if (srcX == destX || srcY == destY) { if (Math.abs(srcX - destX) == 1 || Math.abs(srcY - destY) == 1) { for (var i = 0; i < jingCanMovePoint.length; i++) { var point = jingCanMovePoint[i]; if (destX == point.x && destY == point.y) { // 然后再去看这些点上有没有棋子 var chess = this._getChess(destX, destY); if (chess) { // 有棋子 return false; } return true; } } return false; } return false; } }, _canMovePao: function (color, srcX, srcY, destX, destY) { // 获得点击坐标处的所有xy上面的棋子状态 var allCanMovePoint = this._getXAndYChesss(srcX, srcY); // 想办法获得横纵坐标上面一旦有棋子之间的坐标 // 这几个数组主要用于存储我点击的位置上下左右四个方向第一次出现棋子到我现在这个棋子之间的棋子状态 var rightChess = this._getRightChesses(srcX, srcY); var leftChess = this._getLeftChesses(srcX, srcY); var upChess = this._getUpChesses(srcX, srcY); var downChess = this._getDownChesses(srcX, srcY); // 开始实现移动车的规则. for (var i = 0; i < allCanMovePoint.length; i++) { var point = allCanMovePoint[i]; if (destX == point.x && destY == point.y) { // 如果我当前要移动的点在我的这个点集合中 if (!point.tag) { //而且这个位置没有棋子 // 开始进一步限定移动的范围 // 上 if (destY < srcY) { for (var j = 0; j < upChess.length; j++) { // 取出可以向上移动的所有棋子的位置 var chess = upChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 下 if (destY > srcY) { for (var j = 0; j < downChess.length; j++) { var chess = downChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 左 if (destX < srcX) { for (var j = 0; j < leftChess.length; j++) { var chess = leftChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } return false; } // 右 if (destX > srcX) { for (var j = 0; j < rightChess.length; j++) { var chess = rightChess[j]; // 如果我点击的位置在这个集合里面 if (destX == chess.x && destY == chess.y) { if (!chess.tag) { // 没有棋子 return true; } } } } return false; } } } return false; }, _canMoveBing: function (color, srcX, srcY, destX, destY) { // 兵的走棋规则: 只能走直线, 只能向前走, 过了河之后可以左右走 var isGoRiver = false; // 默认情况下没有过河 // 要想左右走, 必须先过河 if (color == "black") { if (srcY != 5 && srcY != 6) { isGoRiver = true; } } else { if (srcY != 3 && srcY != 4) { isGoRiver = true; } } // 黑色棋子的可以移动方向:上,左,右 if (color == "black") { // 可以向上下左右四个方向来移动棋子 if (destY < srcY) { //向上 //获得可以向上行走的位置 var upChess = this._getUpChesses(srcX, srcY); for (var i = 0; i < upChess.length; i++) { var chess = upChess[i]; if (destX == chess.x && destY == chess.y) { // 如果我点击的位置在我向上走的这个集合里面 if (!chess.tag) { // 而且这个位置没有棋子 // 每次移动的间隔为1 if (Math.abs(destX - srcX) == 1 || Math.abs(destY - srcY) == 1) { return true; } } } } } } // 红色棋子的移动方向:下,左, 右 if (color == "red") { if (destY > srcY) { // 向下 //获得可以向上行走的位置 var downChess = this._getDownChesses(srcX, srcY); for (var i = 0; i < downChess.length; i++) { var chess = downChess[i]; if (destX == chess.x && destY == chess.y) { // 如果我点击的位置在我向上走的这个集合里面 if (!chess.tag) { // 而且这个位置没有棋子 // 每次移动的间隔为1 if (Math.abs(destX - srcX) == 1 || Math.abs(destY - srcY) == 1) { return true; } } } } } } // 向左行走 if (destX < srcX && isGoRiver) { // 向左 //获得可以向左行走的位置 var leftChess = this._getLeftChesses(srcX, srcY); for (var i = 0; i < leftChess.length; i++) { var chess = leftChess[i]; if (destX == chess.x && destY == chess.y) { // 如果我点击的位置在我向上走的这个集合里面 if (!chess.tag) { // 而且这个位置没有棋子 // 每次移动的间隔为1 if (Math.abs(destX - srcX) == 1 || Math.abs(destY - srcY) == 1) { return true; } } } } } // 向右走 if (destX > srcX && isGoRiver) { // 向右 //获得可以向右行走的位置 var rightChess = this._getRightChesses(srcX, srcY); for (var i = 0; i < rightChess.length; i++) { var chess = rightChess[i]; if (destX == chess.x && destY == chess.y) { // 如果我点击的位置在我向上走的这个集合里面 if (!chess.tag) { // 而且这个位置没有棋子 // 每次移动的间隔为1 if (Math.abs(destX - srcX) == 1 || Math.abs(destY - srcY) == 1) { return true; } } } } } }, _moveChess: function (srcX, srcY, destX, destY) { // 移动棋子 this._selectedChess.x = destX; this._selectedChess.y = destY; // 颜色恢复 this._selectedChess.color = this._selectedChess.chessColor; // 吃完棋子之后, 就恢复到初始状态 this._selectedChess = null; }, _getMovePoint: function (srcX, srcY) { // 主要用于获得一个点的8个方向上面的棋子状态 var x = srcX; var y = srcY; var movePoint = []; for (var i = x - 1; i <= x + 1; i++) { for (var j = y - 1; j <= y + 1; j++) { //首先判断该点是否在棋盘内 if ((i >= 0 && i <= 8) && (j >= 0 && j <= 9)) { //接着判断该点有无棋子 var tag = false;//假设该点没有棋子 for (var m = 0; m < this._chesses.length; m++) { var chess = this._chesses[m]; if (!chess.isDead) { if (i == chess.x && j == chess.y) { tag = true;//说明有棋子 break; } } } movePoint.push({ x: i, y: j, tag: tag }); } } } return movePoint; }, _getXAndYChesss: function (srcX, srcY) { // 求出来车可以移动的所有的位置 var MovePoint = []; var allCanMovePoint = []; var tagColor; // 找出x坐标上的所有点 for (var i = 0; i < 10; i++) { MovePoint.push({ x: srcX, y: i }); } // 找出y坐标上的所有点 for (var j = 0; j < 9; j++) { MovePoint.push({ x: j, y: srcY }); } // 车的行走规则:走直线,只要直线上没有棋子都可以走: 只能走srcX或者srcY方向上面的直线 var tag = false; // 默认没有棋子 for (var i = 0; i < MovePoint.length; i++) { var point = MovePoint[i]; // 再看这些个坐标点上面有没有棋子 var chess = this._getChess(point.x, point.y); if (chess) { tag = true; tagColor = chess.chessColor; } else { tag = false; } // 把这些点的状态记录下来 allCanMovePoint.push({ x: point.x, y: point.y, tag: tag, chessColor : tagColor }); } return allCanMovePoint; }, _getRightChesses: function (srcX, srcY) { var rightChess = []; // 获得这个棋子之后的所有棋子 var firstChess = 0; var tagColor = ""; for (var i = srcX; i <= 8; i++) { var tag = false; // 此时这个位置之后的棋子x坐标为srcX, srcX+1, ...... // y坐标一直未scrY // 判断这个位置有没有棋子 var chess = this._getChess(i, srcY); if (chess) { tag = true; tagColor = chess.chessColor; firstChess++; } rightChess.push({ x: i, y: srcY, tag: tag, // 这里添加一个属性 chessColor : tagColor }); // 存储完毕之后,恢复初始状态 tagColor = ""; // 一旦有棋子就退出 if (firstChess == 2) { firstChess = 0; // 恢复初始状态 break; } } return rightChess; }, _getLeftChesses: function (srcX, srcY) { var leftChess = []; var firstChess = 0; var tagColor = ""; // 点击位置左边的所有棋子 for (var i = srcX; i >= 0; i--) { var tag = false; // 此时这个位置之后的棋子x坐标为srcX-1, srcX-2, ...... // y坐标一直未scrY // 判断这个位置有没有棋子 var chess = this._getChess(i, srcY); if (chess) { tag = true; firstChess++; tagColor = chess.chessColor; } leftChess.push({ x: i, y: srcY, tag: tag, // 这里添加一个属性 chessColor : tagColor }); // 存储完毕之后,恢复初始状态 tagColor = ""; // 一旦有棋子就退出 if (firstChess == 2) { firstChess = 0; // 恢复初始状态 break; } } return leftChess; }, _getUpChesses: function (srcX, srcY) { var upChess = []; var firstChess = 0; var tagColor = ""; // 点击位置上面的所有棋子 for (var i = srcY; i >= 0; i--) { var tag = false; // 此时这个位置之后的棋子y坐标为srcY+1, srcY+2, ...... // x坐标一直未scrX // 判断这个位置有没有棋子 var chess = this._getChess(srcX, i); if (chess) { tag = true; firstChess++; tagColor = chess.chessColor; } upChess.push({ x: srcX, y: i, tag: tag, // 这里添加一个属性 chessColor : tagColor }); // 存储完毕之后,恢复初始状态 tagColor = ""; // 一旦有棋子就退出 if (firstChess == 2) { firstChess = 0; // 恢复初始状态 break; } } return upChess; }, _getDownChesses: function (srcX, srcY) { var downChess = []; var firstChess = 0; var tagColor = ""; // 点击位置下面的所有棋子 for (var i = srcY; i <= 9; i++) { var tag = false; // 此时这个位置之后的棋子y坐标为srcY+1, srcY+2, ...... // x坐标一直未scrX // 判断这个位置有没有棋子 var chess = this._getChess(srcX, i); if (chess) { tag = true; firstChess++; tagColor = chess.chessColor; } downChess.push({ x: srcX, y: i, tag: tag, // 这里添加一个属性 chessColor : tagColor }); // 存储完毕之后,恢复初始状态 tagColor = ""; // 一旦有棋子就退出 if (firstChess == 2) { firstChess = 0; // 恢复初始状态 break; } } return downChess; }, _canKill: function (srcX, srcY, destX, destY) { // 象棋的吃子功能介绍 //1. 如果两次点击的棋子颜色不同 //2. 看是否满足象棋的走棋规则 //3. 如果满足象棋的走棋规则, 而且两次点击的颜色不同我就可以吃子 // 点击棋子的颜色和吃子的颜色 var srcChess = this._getChess(srcX, srcY); var killChess = this._getChess(destX, destY); var color = srcChess.chessColor; // 如果这两个位置都有棋子(吃子的前提是两次点击的位置都有棋子) if (srcChess != null && killChess != null){ // 看两次的颜色是不是相同 if (srcChess.chessColor != killChess.chessColor){ // 可以吃 // 然后在我吃棋子之前再判断这个棋子能不能移动 var type = srcChess.type; // 根据这个棋子的规则来判断 switch (type) { case "CHE": if (this._canMoveChe(color, srcX, srcY, destX, destY)) { // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) /*srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true;*/ return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "MA": if (this._canMoveMa(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "XIANG": if (this._canMoveXiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "SHI": if (this._canMoveShi(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "JIANG": if (this._canMoveJiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "PAO": if (this._canMovePao(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } case "BING": if (this._canMoveBing(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); // 开始吃棋子 this._moveChess(srcX, srcY, destX, destY); // 吃完棋子之后的操作(我方棋子补上) srcChess.x = destX; srcChess.y = destY; // 对方棋子消失 killChess.isDead = true; return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert("不能移动棋子!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; } } else { // 如果点击的棋子颜色相同 alert("请不要互相残杀!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } } else if(srcChess != null && killChess == null){ // 用户走棋的操作肯定是OK的 var type = srcChess.type; // 表示要移动棋子 // 首先看能不能移动 // 我们先来判断能不能移动棋子, 然后再来判断能不能吃子 switch (type) { case "CHE": if (this._canMoveChe(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "MA": if (this._canMoveMa(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "XIANG": if (this._canMoveXiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "SHI": if (this._canMoveShi(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "JIANG": if (this._canMoveJiang(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; case "PAO": if (this._canMovePao(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } case "BING": if (this._canMoveBing(color, srcX, srcY, destX, destY)) { // 移动棋子 this._moveChess(srcX, srcY, destX, destY); return; } else { // 点击了颜色相同但是属性不同的其他棋子 alert(srcChess._getChessText()+"走法违规!"); // 颜色相同的同类棋子就恢复初始状态 this._selectedChess.color = this._selectedChess.chessColor; this._selectedChess = null; return; } break; } } }, _getChess: function (x, y) { for (var i = 0; i < this._chesses.length; i++) { var chess = this._chesses[i]; if (!chess.isDead) { if (chess.x == x && chess.y == y) { return chess; } } } return null; } } var myGame = new Game(); myGame.execute(); </script> </body> </html>

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的选择框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123799 // 选择框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 xframe.extend(xframe, { /** * ID选择器 * @param context * @return {HTMLElement | *} */ $id: function (context) { // context是一个DOM对象还是字符串 context = this.isString(context) ? document.getElementById(context) : context; return context; }, /** * tag选择器, context;里面存储了上下文信息(尽量少的使用局部变量) * @param tag * @param context * @return {NodeListOf<HTMLElementTagNameMap[keyof HTMLElementTagNameMap]>} */ $tag: function (tag, context) { // 分为两种情况 if (typeof context === 'string') { context = this.$id(context); } // 按照这种思路,只有可能是一种情况 if (context) { if (context.length) { // 这里默认只会返回数组中的第0个元素 return [].slice.call(context)[0].getElementsByTagName(tag); } else { return context.getElementsByTagName(tag); } } return document.getElementsByTagName(tag); }, /** * 实现一个类选择器 * @param className * @param context * @return {*} */ $class: function (className, context) { // context里面此时存储的是一个DOM节点元素 // 如果直接传过来的是一个DOM元素节点context(DOM元素的话就单独处理) context = this.$id(context) || document; // 1.由于getElementByClassName()这个方法是不兼容的,因此需要使用浏览器内置的方法去获取类选择器 // 2. 可以使用getElementByTagName()的方法去获取所有的标签元素,然后把再使用className的属性间接去实现一个类似的class选择器的功能 if (context.getElementsByClassName) { // 如果支持这个方法的话 return context.getElementsByClassName(className); } else { // 不支持的话就间接获取 var doms = context.getElementsByTagName('*'), res = []; // 使用自己定义的方法去实现一个类选择器 doms.each(function () { if (this.className === className) { // 只要是找到了这个class的集合,就放入到一个数组里面 res.push(this); } }); return res; } }, /** * 使用管道思想实现一个层次选择器 * @return {Array} */ $cengci: function () { var self = this; // 主要功能:实现一个层次选择器 // 输入字符串: str = '#className div a p' 选择所有的className 下面的P标签 // 1. 获取穿过来的参数(数组元素去重) var args = Array.prototype.slice.call(arguments)[0].toString().split(' '), index, first, item, selector, res = [], // 存储了本次的结果信息 context = []; // 存储了上一次的上下文信息【管道思想!】, context = 'tag .class #id' // 思考: 为了实现一个层次选择器, 如何实现一个吧上一次选择的元素全部存储起来??? // 2. 开始解析参数信息 args.each(function () { // 每次重复之前,先把本次需要存储的数组清空(res里面存储了每次的最新数据) res = []; // 对获取到的每一项进行处理 item = this.trim(); first = item.charAt(0); index = item.indexOf(first); selector = item.slice(index + 1); // 使用管道思想实现一个层次选择器!!! switch (first) { case '.': // class 选择器 if (context.length) { // 说明这一次的class类选择器中的元素不是第一次出现 context.each(function () { pushArray(self.$class(selector, this)); }); } else { // 如果是第一次出现的话 pushArray(self.$class(selector)); } // 把上一次执行的结果存起来 context = res; break; case '#': // ID选择器 // 由于ID选择器获取的元素始终是唯一的,因此直接放进去即可 res.push(self.$id(selector)); // 把上一次执行的结果存起来 context = res; break; default: // tag选择器 if (context.length) { // 说明不是第一次出现 context.each(function () { // 注意在使用tag选择器的时候,第二个参数必须是一个ID选择器,或者是一个 // 1. 注意在放入数组的时候,需要逐个遍历然后放进去 pushArray(self.$tag(item, this)); }); } else { // 第一次出现的 pushArray(self.$tag(item)); } // 把上一次执行的结果存起来 context = res; break; } }); /** * 把公共的部分代码封装起来 * @param doms */ function pushArray(doms) { if (doms) { [].slice.call(doms).each(function () { res.push(this); }); } } return context; }, /** * group选择器 * @return {Array} */ $group: function () { var self = this; // '.moshou,#moshou,span,.dream' // 1. 获取传过来的参数 var args = [].slice.call(arguments), arr = args[0].split(',').unique(), // 这里在拿到这个分割后的字符串后,开始进行数组元素去重 item, index, first, selector; res = []; // 2. 开始遍历参数集合,解析参数信息 arr.each(function () { // 3. 开始遍历得到结果,获取每一项 item = this.trim(); // 4. 开始获取首字母信息,和后面的选择器信息 // 4. 获取指定下标位置对应的字符 first = item.charAt(0); index = item.indexOf(first); selector = item.slice(index + 1); // 开始根据第一个字母向下进行判断,把满足相应条件的放在数组里面 switch (first) { case '.': // class选择器 res.push(self.$class(selector)); break; case '#': // ID 选择器 res.push(self.$id(selector)); break; default: // TAG选择器(直接就是first本身,这里不用再判断了使用selector这个变量了) res.push(self.$tag(item)); break; } }); return res; }, /** * 多组+层次选择器 * @return {Array} */ $select: function () { // str = '#tag , .calss' var args = [].slice.call(arguments)[0].toString().split(','), ret = [], self = this; // 遍历args数组,对数组的每一项采用层次选择器 args.each(function () { // 1. 对于逗号分隔的部分采用层次选择,获取层次选择器的结果信息, 是一个数组集合 var res = self.$cengci(this); // 2. 遍历层次选择器的集合,把信息放入到一个新的数组里面, 就是得到的多组选择器的结果信息 pushArray(res); }); // 层次选择器 function pushArray(doms) { if (doms.length) { doms.each(function () { ret.push(this); }); } } return ret; } }); })(xframe);

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的事件框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123753 // 事件框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 实现一个浏览器的基本事件的绑定 * @param type * @param fn * @return {on} */ on: function (type, fn) { // 注意这里的初始的下标编号是长度减一 var i = this.length - 1; // 可以实现兼容版本的IE浏览器和W3c浏览器的支持 if (document.addEventListener) { // w3c(这里使用的方式是从后向前遍历, 使得每一个DOM加载完毕之后再去添加事件) for (; i >= 0; i--) { this[i].addEventListener(type, fn, false); } } else if (document.attachEvent) { // IE for (; i >= 0; i--) { this[i].attachEvent('on' + type, fn); } } else { // 其他的浏览器 for (; i >= 0; i--) { // 获取json数据的两种方式,绑定事件的方式也可以 this[i]['on' + type] = fn; } } return this; }, /** * 实现事件的解除绑定 * @param type * @param fn * @return {un} */ un: function (type, fn) { // 注意这里的初始下标编号 var i = this.length - 1; if (document.removeEventListener) { // W3c for (; i >= 0; i--) { this[i].removeEventListener(type, fn, false); } } else if (document.detachEvent) { // IE浏览器 for (; i >= 0; i--) { this[i].detachEvent(type, fn); } } else { // 其他浏览器的话,就直接默认绑定的所有事件置为null for (; i >= 0; i--) { // 移出所有绑定的事件 this[i]['on' + type] = null; } } return this; }, /** * 实现单个元素的事件绑定 * @param fn * @return {click} */ click: function (fn) { this.on('click', fn); return this; }, /** * 实现鼠标移动进来和出去的事件响应(鼠标悬浮事件) * @param fnOver * @param fnOut * @return {hover} */ hover: function (fnOver, fnOut) { var i = this.length; // 还是采用的是从后向前遍历的方式 for (; i >= 0; i--) { if (fnOver && typeof fnOver === 'function') { this.on('mouseover', fnOver); } if (fnOut && typeof fnOut === 'function') { this.on('mouseout', fnOut); } } return this; }, /** * 如果被选元素可见,则隐藏这些元素,如果被选元素隐藏,则显示这些元素。 * toggle方法,切换,接收任意个参数,不断在参数间循环.例:点击显示隐藏 * @return {toggle} */ toggle: function () { // 实现一个事件的切换f1, f2 var self = this, _arguments = arguments, i = 0, len = this.length; // 把所有的事件响应函数存起来 for (; i < len; i++) { addToToggle(this[i]); } /** * 鼠标点击之后逐个调用自己绑定的事件 * @param obj */ function addToToggle(obj) { // 定义一个私有的计数器 var count = 0; // 添加事件 self.on('click', function () { // 使用call去修改this的指向(这里的主要作用是去切换,轮巡切换状态) _arguments[count++ % _arguments.length].call(obj); }); } return this; } }); // 不需要参与链式访问的 xframe.extend(xframe, { /** * 获取事件对象 * @param event * @return {Event} */ getEvent: function (event) { return event ? event : window.event; }, /** * 获取触发事件的元素 * @param event * @return {*|Element|Object} */ getTarget: function (event) { var event = this.getEvent(event); return event.target || event.srcElement; }, /** * 阻止事件冒泡 * @param event */ stopPropagation: function (event) { var event = this.getEvent(event); if (event.stopPropagation) { // W3c event.stopPropagation(); } else { // IE event.cancelBubble = true; } }, /** * 阻止默认的行为 * @param event */ preventDefault: function (event) { var event = this.getEvent(event); if (event.preventDefault) { // w3c event.preventDefault(); } else { // IE event.returnValue = false; } }, /** * 获取鼠标滚轮的运动的详细信息 * @param event * @return {*} */ getDelta: function (event) { var event = this.getEvent(event); if (event.wheelDelta) { // w3c return event.wheelDelta; } else { // ie // Firefox的值有所不同,因此首先要将这个值的符号反向,然后再乘以40,就可以保证与其它浏览器的值相同了 return -event.detail * 40; } } }); })(xframe);

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的缓存框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123863 // 缓存框架 (function (xframe) { /** * 实现了缓存框架的临时存储功能(内存存储) * @type {{data: Array, get: (function(*): *), add: xframe.cache.add, delete: (function(*): boolean), update: (function(*, *): boolean), isExist: (function(*): boolean)}} */ xframe.cache = { data: [], // 用于存储本地的数据信息 /** * 用于获取本地存储的json数据信息 * @param key * @return {*} */ get: function (key) { var value = null; this.data.each(function () { if (key.trim() === this.key.trim()) { value = this.value; } }); return value; }, /** * 向本地存储添加数据信息 * @param key * @param value */ add: function (key, value) { this.data.push({ key: key.trim(), value: value.trim() }); }, /** * 删除指定的key的数据信息 * @param key * @return {boolean} */ delete: function (key) { // 删除指定的key对应的数据信息 var status = false, // 定义一个状态码,用于标记删除是否成功的状态信息 self = this; this.data.forEach(function (element, index) { // 遍历本地的数据存储信息,进行比对数据信息 if (key.trim() === element.key.trim()) { // 指定开始的位置,开始删除数组中的数据信息 self.data.splice(index, 1); status = true; } }); return status; }, /** * 修改指定的元素的数据信息 * @param key * @param value */ update: function (key, value) { var status = false; this.data.forEach(function (element) { if (key.trim() === element.key) { // key不变,只修改数值信息, 注意element是一个json对象,这个对象里面包含了两个属性element.key和element.value这两个 element.value = value.trim(); status = true; } }); return status; }, /** * 检测一个指定的数据是否存在 * @param key * @return {boolean} */ isExist: function (key) { // 用于检测某一个数据信息是否存在 this.data.forEach(function () { if (key.trim() === this.key) { return true; } }); return false; } } /** * 实现了一个Cookie框架的封装(注意在把HTML转换为实体存储的时候这里默认是去掉了最末尾的分号) * @type {{getCookie: xframe.cookie.getCookie, setCookie: xframe.cookie.setCookie, deleteCookie: xframe.cookie.deleteCookie, clearAllCookies: xframe.cookie.clearAllCookies}} */ xframe.cookie = { /** * 根据cookie的名字获取Cookie的详细信息 * @param name * @return {*} */ getCookie: function (name) { // 去除转义字符 var name = name.escapeHTML(), // 读取文档中的所有cookie属性 allCookies = document.cookie; // 下面是一些Cookie的数据格式信息(默认返回的是一个字符串) // H_PS_645EC=af88R0s3e76Ig1PlwkvrhnGGtg4qt5pcZNPKBUntPI2vGearAlyZyjXjmKYn%2BkggUXbNjhg; // 1. 查找名称为name的cookie信息script3&amp5; //name = name.substring(0, name.length-1); // 当前步骤是为了去除掉末尾的分号(转换为标准形式); name += '='; // 等号右边的就是获取的数值,左边就是cookie的名称信息 // 2. 获取'name='这个字符串在整个Cookie信息字符串中出现的位置下标 var pos = allCookies.indexOf(name); // 3. 判断是否存在这个cookie的信息 if (pos !== -1) { // 如果存在的话,就继续处理 // 3. 计算'cookie='等号后面的位置 var start = pos + name.length; // 3. 从'cookie='的位置开始向后搜索, 一直到;的位置结束, 从start的位置向后搜索信息 var end = allCookies.indexOf(';', start); if (end === -1) { // 如果为-1的话, 说明cookie信息列表里面只有一个Cookie信息 end = allCookies.length; } // 4. 提取Cookie的数值信息 var value = allCookies.substring(start, end); // 5.处理之后反转义后返回(反转义的目的是将内容进行加密处理,防止攻击)【测试状态OK,由于之前的内部存储,必须先删除所有的,在执行就ok了】 return value.unescapeHTML(); } else { // 没有找到, 说明不存在这个cookie信息 return ''; } // 默认情况下返回一个空的字符串 return ''; }, /** * 根据传入的参数信息设置浏览器的cookie * @param name * @param value * @param days * @param path */ setCookie: function (name, value, days, path) { var name = name.escapeHTML(), value = value.escapeHTML(), expires = new Date(), _expires, res; //name = name.substring(0, name.length-1); // 当前步骤是为了去除掉末尾的分号(转换为标准形式); // 设置cookie的过期时间(单位是毫秒) expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); if (path === '') { path = ''; } else { path = (';path=' + path); } if (typeof expires === 'string') { _expires = ''; } else { // 使用UTC标准时间 _expires = (';expires=' + expires.toUTCString()); } // 设置cookie信息,【注意要点:】(设置COokie的时候,只要遇到分号就会立即结束,只会保存分号之前的内容) res = name + '=' + value + _expires + path; // document.cookie="userId=828; userName=hulk"; document.cookie = res; }, /** * 根据名称信息和路径信息删除cookie * @param name * @param path */ deleteCookie: function (name, path) { var name = name.escapeHTML(), expires = new Date(); if (path === '') { path = ''; } else { path = (';path=' + path); } // 删除之后重新设置cookie document.cookie = name + '=' + ';expires=' + expires.toUTCString() + path; }, /** * 清空所有的cookie信息 */ clearAllCookies: function () { // 1. 获取浏览器中存储的所有cookie信息 // "name&amp=xiuxiu&amp; name=xiuxiu; script=<script>alert(2); script2=<script>alert(2); script3=<script>alert(2); script3&amp=&ltscript&gtalert(2); script4&amp=&ltscript&gtalert(2); a&amp=&lta&gtalert(2)&lt/a&gt&amp" var cookies = document.cookie.split(';'); if (cookies.length) { cookies.forEach(function (element) { // 拿到字符串:name&amp=xiuxiu&amp var index = element.indexOf('='), name = element.substring(0, index); // 实现思路:要想删除某一个COOkie信息,只需要将cookie的name对应的值设置为空即可 document.cookie = name + '=' + ';expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'; }); } } } // 本地存储框架localstorage的本地存储 xframe.store = (function (xframe) { // 定义一个API,用于定义实现的本地存储的API接口 var api = {}, localStorageName = 'localStorage', globalStorageName = 'globalStorage', win = window, doc = window.document, storage; // 首先先定义要实现的功能接口 api.set = function (key, value) { } api.get = function (key) { } api.remove = function (key) { } api.clear = function () { } /* * a) sessionStorage和localStorage都是window的属性,也是Storage对象的实例,即:window.sessionStorage instanceof Storage返回True,window.localStorage instanceof Storage 返回True,也因此两者享有Storage的属性和方法。 b) sessoinStorage存储的数据在页面会话结束时会被清空,页面会话在浏览器窗口关闭前持续存在,包含页面刷新和恢复。若新开标签或窗口将新建一个会话,再次获取sessionStorage将只限于当前会话,与先前会话的无关。localStorage存储的数据不会 c) window.globalStorage自Gecko 13 (Firefox 13)起不再支持。 * * */ if (localStorageName in win && win[localStorageName]) { // 拿到本地存储的这个数据项 storage = win[localStorageName]; // 实现我自己定义的接口 /** * 设置本地存储的内容 * @param key * @param value */ api.set = function (key, value) { storage.setItem(key, value); } /** * 获取本地存储的内容 * @param key * @return {*} */ api.get = function (key) { return storage.getItem(key); } /** * 移出其中的某一项 * @param key */ api.remove = function (key) { storage.removeItem(key); } /** * 清空本地存储的所有内容 */ api.clear = function () { storage.clear(); } } else if (globalStorageName in win && win[globalStorageName]) { // HTML5中的localStorage替换了原来的globalStorgae // 1. 拿到本地存储的对象(这是一个Json对象)[Firefox浏览器] storage = win[globalStorageName][win.location.hostname]; api.set = function (key, value) { storage[key] = value; } api.get = function (key) { return storage[key] && storage[key].value; } api.remove = function (key) { // delete用来删除一个对象的属性。 delete storage[key]; } api.clear = function () { for (var key in storage) { delete storage[key]; } } } else if (doc.documentElement.addBehavior) { // 如果可以给一个对象添加行为的话 // 单独定义一个获取本地存储的对象storage function getStorage() { // 如果已经获取到了Storage对象的话 if (storage) { return storage; } storage = doc.body.appendChild(doc.createElement('div')); storage.style.display = 'none'; // userData 64KB IE专用 storage.addBehavior('#default#userData'); // 这个是微软自定义的一个本地存储,相比之下有更大的容量 storage.load(localStorageName); return storage; } api.set = function (key, value) { var storage = getStorage(); // 设置属性 storage.setAttribute(key, value); // 保存属性信息 storage.save(localStorageName); } api.get = function (key) { var storage = getStorage(); return storage.getAttribute(key); } api.remove = function (key) { var storage = getStorage(); storage.removeAttribute(key); // 移出数据之后记得保存一下数据 storage.save(localStorageName); } api.clear = function () { // 1. 获取Storage对象 var storage = getStorage(); // 2.获取storage对象存储的所有属性信息 var attributes = storage.XmlDocument.documentElement.attributes; storage.load(localStorageName); // 3. 遍历所有的属性信息,并从本地移出数据 [].slice.call(attributes).forEach(function (element) { storage.removeAttribute(element.name); }) // 4. 移出完毕之后,开始保存信息到本地存储 storage.save(localStorageName); } return api; } // 把立即函数里面的私有成员暴露出去(如果在立即函数内部不暴露出去需要使用的成员,在外部是无法访问到内部的私有成员变量的) xframe.storage = api; })(xframe); })(xframe);

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的DOM框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123835 // DOM框架(选择器框架) (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 向现有的元素集合中添加元素节点(修改this的内容) * @param dom * @return {add} */ add: function (dom) { // 1. 项伪数组中添加元素 this[this.length] = dom; // 2. 数组的长度也需要改变了 this.length++; return this; }, /** * 向现有的元素节点中添加dom节点(对使用选择器获取的一系列元素都添加孩子节点child) * @param child,这里创建的实际上是一个JQuery对象 */ append: function (child) { // 这里获取的实际上就是只有一个的 var doms = typeof child === 'string' ? $(child) : $(child[0]), arr = Array.prototype.slice.call(doms); //console.log(typeof doms[0], typeof arr[0]); // 2. 调用自己的方法将一个伪数组转换为数组,并开始遍历 /*for (var i = 0; i < this.length; i++){ for (var j = 0; j < doms.length; j++){ // 注意这里的操作, 由于在每次添加一个新的元素之后, this的长度就会增加,因此这里在修改之前先把this.length修改一下 this[i].appendChild(doms[j]); } }*/ /*this.each(function (element) { arr.forEach(function (childNode) { element.appendChild(childNode); }); });*/ // 这里的处理目的是,如果穿过来的DOM节点只是有一个的话需要创建和this长度相同的DOM元素 if (arr.length !== this.length) { arr = []; // 相当于是把本身复制几份 Array.prototype.slice.call(this).each(function () { arr.push(doms[0]); }); } // 开始向父亲节点添加元素 Array.prototype.slice.call(this).forEach(function (element, index) { element.appendChild(arr[index]); }); // 开始向我获取的this节点里面添加数据 /*for (var i = 0; i < this.length; i++){ for (var j = 0; j < arr.length; j++){ if (this[i].childNodes){ continue; } // 注意这里的操作, 由于在每次添加一个新的元素之后, this的长度就会增加,因此这里在修改之前先把this.length修改一下 this[i].appendChild(arr[j]); } }*/ }, /** * 把选择器中的节点添加到父容器中 * @param parent */ appendTo: function (parent) { // 1. 获取所有的父容器 var doms = $(parent), self = this; // 2. 向父容器中添加孩子节点 Array.prototype.slice.call(this).forEach(function (element, index) { doms[index].appendChild(self[index]); }); return this; }, /** * 获取指定下表下面的DOM节点 * @param num * @return {null} */ get: function (num) { return this[num] ? this[num] : null; }, /** * 获取一个类似于JQuery的对象实例 * @param num * @return {jQuery|HTMLElement} */ eq: function (num) { // 1. 获取一个JQuery对象,首先先获取这个DOM元素节点 var dom = this.get(num); // 2. 把这个DOM节点转换为一个JQuery对象 return $(dom); }, /** * 获取第一个JQuery对象 * @return {*|jQuery|HTMLElement} */ first: function () { return this.eq(0); }, /** * 获取最后一个JQuery对象 * @return {*|jQuery|HTMLElement} */ last: function () { return this.eq(this.length - 1); }, /** * 获取一个DOM节点的所有子节点 * @return {array} */ children: function () { // 获取一个元素的所有的孩子节点 // 1. 定义一个伪数组, 用于存储所有的孩子节点, 然后获取默认的第一个元素的所有孩子节点 var children = this[0].children, len = children.length, that = {}, i = 0; // 初始化定义的这个伪数组 that.length = len; for (; i < len; i++) { that[i] = children[i]; } return that; }, /** * 从当前DOM元素节点向下寻找一层元素节点 * @param str * @return {} */ find: function (str) { var res = [], self = this, doms; this.each(function () { switch (str.charAt(0)) { case '.': // 类选择器 doms = $.$class(str.substring(1), self[i]); pushArray(doms); break; default: // 标点选择器 doms = $.$tag(str, self[i]); pushArray(doms); break; } }); function pushArray(doms) { if (doms.length) { self.toArray(doms, function () { res.push(this); }); } } // 【注意:】为了能够返回一个JQuery对象,这里需要再次进行处理 var that = this; that.length = this.length; this.each(function (index) { // 这里需要再次构造一个伪数组对象,从而实现链式访问的功能 that[index] = res[index]; }); // 这里在修改that的时候实际上会间接地把this这个变量修改了 return that; }, /** * 获取一个元素的父类节点 * @return {parent} */ parent: function () { // 获取父节点,并且返回一个JQuery对象 var parent = this[0].parentNode; this[0] = parent; this.length = 1; // 由于每一个元素只会有一个父类节点,因此长度为1 return this; }, /** * 获取一个元素在同一个级别的元素里面的下表编号 * @return {number} */ index: function () { // 获取元素本身在同一个级别下面的元素下表编号 var srcNode = this[0], children = srcNode.parentNode.children, self = this, defaultRes = -1; self.toArray(children, function (index) { // 这里的this指向的就是每一个元素, index指向的就是元素的下表编号 if (children[index] === srcNode) { defaultRes = index; } }); // 返回查询到的结果下标 return defaultRes; } }); // 不需要参与链式访问的 xframe.extend(xframe, { /** * 创建一个DOM元素节点 * @param type * @param value * @param html * @return {*} */ create: function (type, value, html) { var dom = document.createElement(type); return xframe().add(dom).attr(value).html(html); }, /** * 直接的孩子节点 * @param dom * @param tag * @return {jQuery|HTMLElement} */ directChildren: function (dom, tag) { var res = [], tag = tag; if (typeof dom === 'string') { dom = $(dom); } // 如果是一个元素集合的处理方法 if (dom.length) { Array.prototype.slice.call(dom).each(function () { getDOM(this.children); }); } else { // 如果只是一个元素的处理方法 getDOM(dom.children); } /** * 主要用于把满足已知条件的DOM元素集合统一放入到一个新的res数组里面去 * @param doms */ function getDOM(doms) { Array.prototype.slice.call(doms).each(function () { if (this.tagName.toLowerCase() === tag.toLowerCase()) { res.push(this); } }); } // 如果获得了这个直接子节点,就直接返回这个对象 return $(res); }, }); })(xframe);

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的属性框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123810 // 属性框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 获取/设置某一个元素的属性信息 * @return {*} */ attr: function () { // 获取属性信息:两种格式,1. 取值模式 2.设置模式 var args = arguments; if (args.length === 0) { // 没有参数的话,就直接返回本身 return this; } else if (args.length === 1) { // 一个参数的话需要进行判断 if (typeof args[0] === 'string') { // 取值模式 return this[0].getAttribute(args[0]); } else if (typeof args[0] === 'object') { // json对象的话也算是一个设置模式 for (var item in args[0]) { Array.prototype.slice.call(this).each(function () { this.setAttribute(item, args[0][item]); }); } } } else if (args.length === 2) { Array.prototype.slice.call(this).each(function () { this.setAttribute(args[0], args[1]); }); } // 注意这里的this实际上返回的是一个xframe实例对象,但是xframe.eatend(xframe, {})这里的this实际上是一个xframe(selector, context)函数, 还没有实例化呢 return this; }, /** * 判断DOM元素节点是不是拥有某一个属性 * @param val * @return {boolean} */ hasClass: function (val) { if (!this[0]) { return false; } // 默认只会获取第一个元素的相关信息 return this[0].className === val.trim() ? true : false; }, /** * 添加一个class class='xiugang 18 nan' * @param val */ addClass: function (val) { // 处理传进来的字符串两边的空格 val = val.trim(); [].slice.call(this).each(function () { // 只要原来的DOM节点上面没有这个属性的话,就直接添加上去 if (val !== this.className) { this.className += ' ' + val; } }) return this; }, /** * 注意熟练掌握replace()函数的使用 * @param val */ removeClass: function (val) { val = val.trim(); [].slice.call(this).each(function () { if (val === this.className) { // 使用后面替换前面的 this.className = this.className.replace(val, ''); } }) return this; }, /** * 如果有的话就直接删除,没有的话就添加一个 * @param val * @return {toggleClass} */ toggleClass: function (val) { val = val.trim(); [].slice.call(this).each(function () { if (val === this.className) { // 如果有的话就直接删除 this.className.replace(val, ''); } else { // 没有的话就添加一个 this.className += ' ' + val; } }); return this; } }); // 不需要参与链式访问的 xframe.extend(xframe, {}); })(xframe);

优秀的个人博客,低调大师

【JavaScript框架封装】实现一个类似于JQuery的内容框架的封装

版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123820 // 内容框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * .html()用为读取和修改元素的HTML标签 对应js中的innerHTML * @return {html} */ html: function () { var arg = arguments, len = arg.length, arr = Array.prototype.slice.call(this); if (this.length < 1) { return this; } // 分为取值模式和设置模式 if (len === 0) { // 取值模式 return this[0].innerHTML; } else if (len === 1) { // 设置模式 arr.each(function () { this.innerHTML = arg[0]; }); } return this; }, /** * 用于获取文本信息 * @return {*} */ text: function () { var args = arguments, len = args.length; if (this.length === 0) { return this; } if (len === 0) { // 取值模式 return this[0].innerText; } else if (len === 1) { // 设置模式 this.each(function () { this.innerText = args[0]; }); } return this; }, /** * 用于获取表单中的数值(input, form) * @return {*} */ val: function () { // val();设置或者获取表单字段的值(前提是表单设置了value属性); var args = arguments, len = args.length; if (this.length === 0) { return this; } if (len === 0) { return this[0].value; } else if (len === 1) { this.each(function () { this.value = args[0]; }); } return this; } }); // 不需要参与链式访问的 xframe.extend(xframe, {}); })(xframe);

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册