js之翻牌游戏中的一个深刻感悟

先“上菜”:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>记忆方块</title>
 6     <script src="randomNum.js"></script>
 7     <script src="Card.js"></script>
 8     <link rel="stylesheet" href="style.css">
 9 </head>
10 <body>
11 <div id="container"></div>
12 <script src="main.js"></script>
13 </body>
14 </html>
html
 1 #container{
 2     width: 800px;
 3     height: 600px;
 4     background-color: orchid;
 5     border: 3px solid orange;
 6     position: relative;
 7 }
 8 .cardContainer{
 9     width: 50px;
10     height: 50px;
11     overflow: hidden;
12     position: absolute;
13 }
14 .card{
15     width: 100%;
16     height: 100%;
17     margin: 0 auto;
18 }
19 .cardA{
20     background-color: red;
21     font-size: 32px;
22     line-height: 50px;
23     text-align: center;
24     color: aqua;
25 }
26 .cardB{
27     display: none;
28     background-color: blue;
29 }
css
 1 window.meng = window.meng || {};
 2 (function () {
 3 
 4     function createRandom(N) {
 5         var arr = [];
 6         this._randomArr = [];
 7         for (var i = 0; i < N; i++) {
 8             arr[i] = i;
 9         }
10         do {
11             var index = Math.floor(Math.random() * arr.length);
12             var flag = true;
13             this._randomArr.push(arr[index]);
14             arr.splice(index, 1);
15             if (arr.length == 0) {
16                 flag = false;
17             }
18         } while (flag);
19 
20     }
21 
22     Object.defineProperty(createRandom.prototype, "randomArr", {
23         get: function () {
24             return this._randomArr;
25         }
26     });
27     meng.createRandom = createRandom;
28 })();
 1 /**
 2  * Created by Administrator on 2016/8/26.
 3  */
 4 window.meng = window.meng || {};
 5 (function () {
 6 
 7     function Card(num) {
 8         this._aVisible = true;
 9         this._number=num;
10         this._htmlNode = document.createElement("div");
11         this._htmlNode.className = "cardContainer";
12         this._cardA = document.createElement("div");
13         this._cardA.className = "card cardA";
14         this._cardA.innerHTML=""+this._number;
15         this._htmlNode.appendChild(this._cardA);
16         this._cardB = document.createElement("div");
17         this._cardB.className = "card cardB";
18         this._htmlNode.appendChild(this._cardB);
19 
20         var self = this;
21         this._htmlNode.addEventListener("click", function (e) {
22             if (self.onclick) {
23                 self.onclick(self);
24                 // console.log(self);
25             }
26         });
27         //写这句话的意思以后,main里面的  Card.htmlNode.onclick=clickHandle;
28         //就可以了写成  Card.onclick=clickHandle;
29         // 因为这样写就保证了点击的都是Card的节点而不是,Card对象
30     }
31 
32 
33     Object.defineProperties(Card.prototype, {
34         htmlNode: {
35             get: function () {
36                 return this._htmlNode;
37             }
38         },
39         aVisible: {
40             get: function () {
41                 return this._aVisible;
42             }
43         },
44         left: {
45             set: function (value) {
46                 this._htmlNode.style.left = value + "px";
47             }
48         },
49         top: {
50             set: function (value) {
51                 this._htmlNode.style.top = value + "px";
52             }
53         },
54         number: {
55             get: function () {
56                 return this._number;
57             }
58         }
59     });
60     Card.prototype.showA = function () {
61         this._cardA.style.display = "block";
62         this._cardB.style.display = "none";
63         this._aVisible = true;
64     };
65     Card.prototype.showB = function () {
66         this._cardA.style.display = "none";
67         this._cardB.style.display = "block";
68         this._aVisble = false;
69     };
70     meng.Card = Card;
71 })();
 1 /**
 2  * Created by Administrator on 2016/8/26.
 3  */
 4 (function () {
 5 
 6     var N = 10;
 7     var currentNumber = 1;
 8     var cards = [];
 9     var container = document.querySelector("#container");
10 
11     function clickHandle(card) {
12         if (currentNumber == card.number) {
13             container.removeChild(card.htmlNode);
14 
15             var index = cards.indexOf(card);
16             if (index != -1) {
17                 cards.splice(index,1);
18                 if (currentNumber == 1) {
19                     for (var i = 0; i < cards.length; i++) {
20                         cards[i].showB();
21                     }
22                 }
23                 if (cards.length <= 0) {
24                     alert("yes");
25                 }
26             }
27             currentNumber++;
28         } else {
29             alert("no");
30         }
31         //     console.log(card.number);
32 
33     }
34 
35 
36     function addCard() {
37         var randomLeft = new meng.createRandom(N);
38         var randomTop = new meng.createRandom(N);
39 
40         for (var i = 0; i < N; i++) {
41             var Card = new meng.Card(i+1);
42             cards.push(Card);
43             Card.left = randomLeft.randomArr[i] * 50;
44             Card.top = randomTop.randomArr[i] * 50;
45             container.appendChild(Card.htmlNode);
46             Card.onclick=clickHandle;
47             /*
48             *这里有个死循环:number是Card的属性,而onclick点击的应该是Card.htmlNode,
49             *而onclick只能接受一个单个功能,而不能带参数,所以就不能在clickHandle中设置
50             * card为Card.htmlNode了,它里面的card只能接受Card。
51             * 所以要在Card里面写上
52             * var self = this;
53             * this._htmlNode.addEventListener("click", function (e) {
54             * if (self.onclick) {
55             * self.onclick(self);
56             * }
57             * });
58             * 代码,原因在Card.js里面已经写明白了。
59             * */
60 
61         }
62     }
63 
64     function init() {
65         currentNumber = 1;
66         addCard();
67     }
68 
69     init();
70 })();

“这道菜”的有个特别重要的一点,感觉还挺重要的,特此强行解释一波。╮(╯▽╰)╭

这个翻牌游戏中,我用了个Card函数去生产卡片,再在main函数里面去对个生产。

当点击的时候有个重大问题:点击的对象应该是Card.htmlNode这个div,不应该是Card对象。

而我代码中写的

  Card.onclick=clickHandle;
onclick接受的只能是function,顾function不能待参数,而clickHandle中必须对一个形参进行操作,而这个形参只能是Card。
这就出现了问题,onclick的行使对象"只能"是Card.htmlNode,而onclick实行的function只能用Card做参数。
这就不统一了,(Card.htmlNode与Card明显不同啊)。
所以应解决一遍问题,让这一边去符合另一边,引出了解决问题的思路就是:
  
   var self = this;
     this._htmlNode.addEventListener("click", function (e) {
            if (self.onclick) {
                self.onclick(self);
               // console.log(self);
            }
       });
先用self接受this(也就是Card对象)。
设置当htmlNode被点击的时候,执行self.onclick,也就是Card.onclick
这里巧妙地把htmlNode的点击引到了Card的点击上。
归结一句话:当Card.htmlNode点击的时候行使的功能变成了Card点击行使改功能
原文地址:https://www.cnblogs.com/chenluomenggongzi/p/5811380.html