利用事件委托写一个简易扫雷游戏

来源:互联网 发布:kindle淘宝上保护套 编辑:程序博客网 时间:2024/06/06 04:42

1. 事件代理(委托)

可以解决的问题:如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能
基本原理:事件委托是利用事件的冒泡原理来实现的,何为事件冒泡(事件从最深的节点开始,然后逐步向上传播事件)
事件代理的适用场景:应用频繁触发事件时 || 当列表频繁创建删除时

2. 一个简易的扫雷游戏

我是从下面几步来完成的:
(1). 先完成界面的设计(界面的初始方块与初始数组的大小是对应的)
(2). 添加点击事件(利用事件委托)
(3). 完成事件触发调用的函数(在这个过程中需要计算“九宫格”雷区的数目)
(4). 写一个随机生成雷区的函数


界面的样式以及布局

*{    margin : 0;    padding: 0;}body {    font-family: "微软雅黑";    font-size: 14px;    background : #615454;}.box {    width: 320px;    position: fixed;    left: 50%;    top: 20%;    margin-left: -160px;    background: #fff;}.box span{    width: 30px;    height: 30px;    display: block;    border: 1px solid #ddd;    float: left;    background : #b3a157;    cursor: pointer;    text-align: center;    line-height: 30px;}.box span.danger{    background: black;}.box span.safety{    background: white;}
<div id="box" class='box'></div>

初始化界面的代码:

controller.draw = function() {    var html = '';    for(var i = 0, len = controller.arr.length; i < len; i++) {        for(var j = 0, len1 = controller.arr[i].length; j < len1; j++) {            html += "<span></span>";        }        html += '<br>';    }    controller.box.innerHTML = html;    }controller.arr = [    [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],    [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],    [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],    [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],];

事件委托的代码

在这里我把span的点击事件委托给div,给div添加了点击事件,通过event对象可以得到鼠标点击的元素,通过event获得点击的位置,计算出发生点击的span横纵坐标,计算出九宫格内的地雷数目并显示

controller.clickEve = function() {    window.addEventListener ? controller.box.addEventListener('click', controller.gover, false) : attachEvent('onclick', controller.gover); }
controller.gover = function(eve) {    eve = eve || window.event;    var num = 0,         i = 0,        j = 0,        targetElement = eve.target || eve.srcElemeent,        pointerXY = controller.getPointer(eve),        boxOffsetLeft = controller.box.offsetLeft,        boxOffsetTop = controller.box.offsetTop,        relativeLeft = pointerXY.pointerX - boxOffsetLeft,        relativeTop = pointerXY.pointerY - boxOffsetTop;    //x代表行数的下标, y代表列数的下标    i = relativeLeft % 32 == 0 ? Math.floor(relativeLeft / 32 - 1) : Math.floor(relativeLeft / 32);    j = relativeTop % 32 == 0 ? Math.floor(relativeTop / 32 - 1) : Math.floor(relativeTop / 32);    if(controller.arr[i][j] == 1) {        targetElement.className = 'danger';        setTimeout(function() {            alert('游戏结束');            controller.random();            controller.draw();        }, 300);        }else {        for(x = i-1; x <= i+1; x++) {            for(y = j-1; y <= j+1; y++) {                if(x < 0 || y < 0 || x > controller.arr.length-1 || y > controller.arr.length-1) {                    continue;                }                if(controller.arr[x][y] == 1) {                    num++;                }            }        }        targetElement.className = 'safety';        targetElement.innerText = num ? num : "";    }}

出现的效果:

这里写图片描述


整个的JS代码如下,最下面的注释解释了计算九宫格雷的数目的思路:

var controller = function() {}controller.box = document.getElementById('box');controller.draw = function() {    var html = '';    for(var i = 0, len = controller.arr.length; i < len; i++) {        for(var j = 0, len1 = controller.arr[i].length; j < len1; j++) {            html += "<span></span>";        }        html += '<br>';    }    controller.box.innerHTML = html;    }controller.arr = [    [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],    [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],    [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],    [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],    [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],];controller.gover = function(eve) {    eve = eve || window.event;    var num = 0,         i = 0,        j = 0,        targetElement = eve.target || eve.srcElemeent,        pointerXY = controller.getPointer(eve),        boxOffsetLeft = controller.box.offsetLeft,        boxOffsetTop = controller.box.offsetTop,        relativeLeft = pointerXY.pointerX - boxOffsetLeft,        relativeTop = pointerXY.pointerY - boxOffsetTop;    //x代表行数的下标, y代表列数的下标    i = relativeLeft % 32 == 0 ? Math.floor(relativeLeft / 32 - 1) : Math.floor(relativeLeft / 32);    j = relativeTop % 32 == 0 ? Math.floor(relativeTop / 32 - 1) : Math.floor(relativeTop / 32);    if(controller.arr[i][j] == 1) {        targetElement.className = 'danger';        setTimeout(function() {            alert('游戏结束');            controller.random();            controller.draw();        }, 300);        }else {        for(x = i-1; x <= i+1; x++) {            for(y = j-1; y <= j+1; y++) {                if(x < 0 || y < 0 || x > controller.arr.length-1 || y > controller.arr.length-1) {                    continue;                }                if(controller.arr[x][y] == 1) {                    num++;                }            }        }        targetElement.className = 'safety';        targetElement.innerText = num ? num : "";    }}controller.clickEve = function() {    window.addEventListener ? controller.box.addEventListener('click', controller.gover, false) : attachEvent('onclick', controller.gover); }controller.getPointer = function(event) {    var pointerXY = {        pointerX : event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)),        pointerY : event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop))    }     return pointerXY; } controller.random = function() {    for(var i = 0; i < controller.arr.length; i++) {        for(var j = 0; j < controller.arr.length; j++) {            controller.arr[i] = controller.arr[i].sort(function(){                return 0.5-Math.random();   // 0-1  从小到大或者从小到大            });        }    }}//i-1: j-1   i-1 : j   i-1: j+1//i  : j-1    点击处    i  : j+1//i+1: j-1   i+1 : j   i+1: j+1

所写内容如有不足,欢迎指正

0 0
原创粉丝点击