前端筆記之JavaScript面向對象(四)組件化開發&輪播圖|俄羅斯方塊實戰

来源:https://www.cnblogs.com/rope/archive/2019/04/18/10723276.html
-Advertisement-
Play Games

一、組件化開發 1.1組件化概述 頁面特效的製作,特別需要HTML、CSS有固定的佈局,所以說現在越來越流行組件開發的模式,就是用JS寫一個類,當你實例化這個類的時候,頁面上的效果佈局也能自動完成。 實例化後,頁面中就有一個輪播圖的佈局結構,而且可以通過參數傳遞進去。 這個new裡面封裝了HTML、 ...


一、組件化開發

1.1組件化概述

頁面特效的製作,特別需要HTMLCSS有固定的佈局,所以說現在越來越流行組件開發的模式,就是用JS寫一個類,當你實例化這個類的時候,頁面上的效果佈局也能自動完成。

new Carousel();

 

實例化後,頁面中就有一個輪播圖的佈局結構,而且可以通過參數傳遞進去。

這個new裡面封裝了HTMLCSSJS的業務邏輯。組件開發的規律就是所有按鈕、小圓點、圖片等等都是這個類(的實例的)屬性,自己管理自己。

 

組件開發的好處就是在用的時候可以高度自定義,在new的時候應該能傳入一個JSON參數進行配置,當你的JSON裡面的屬性改變的時候,我們的UI界面邏輯就要有響應的變化。

面向對象+設計模式組合各種類(通常是中介者模式),就是組件化開發。

本質思想,組件只考慮兩個事情:

l 別人怎麼控制我,要提供很多函數,這個函數可以改變我的狀態。

我怎麼給別人提供介面,比如輪播圖被點擊時,要提供一個click事件回調。

組件只需要對自己負責,至於別人怎麼調用我的介面,在我提供的介面中做什麼,自己不需要考慮。

 

特點:

組件都是可以單獨測試的,所有組件都可以單獨上樹,進行測試。

DOM都是動態生成的,組件開發中,現在90%以上的,都是將DOM寫在JS中,在“查看源代碼”中看見的是空標簽。

組件是嵌套的,往往大組件是小組件的中介者。

 

優點:

方便維護,功能易於插拔,很容易找出BUG的地方。

l 易於復用,比如我們做一個分頁條組件,此時可以非常自由在其他項目使用。

 

組件開發是一個非常實用的技術,組件開發越來越火,催生了一些組件開發的框架:ReactVueAngular等。


 

1.2輪播圖組件開發

JS對象、DOM對象,JS對象的屬性是DOM對象

用輪播圖的面向對象舉例,JS對象中有自己的參數屬性(比如當前顯示圖片的編號、速度、間隔時間、寬度、高度),還DOM屬性。

<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="js/Carousel.js"></script>
<script type="text/javascript">
     new Carousel({
       "id" : "Carousel",
       "images" : [
           {"picUrl" : "images/0.jpg", "link" : "http://www.iqianduan.cn"},
           {"picUrl" : "images/1.jpg", "link" : "http://www.iqianduan.cn"},
           {"picUrl" : "images/2.jpg", "link" : "http://www.iqianduan.cn"},
           {"picUrl" : "images/3.jpg", "link" : "http://www.iqianduan.cn"},
           {"picUrl" : "images/4.jpg", "link" : "http://www.iqianduan.cn"}
       ],
       "width" : 560,
       "height": 300,
       "speed" : 500,
       "interval" : 2000
     });
</script>

 

 CSS樣式:carousel樣式後面動態創建

#Carousel{
    width: 560px;
    height: 300px;
    position: relative;
    overflow: hidden;
}
.leftBtn,.rightBtn{
    position: absolute;
    top:50%;
    width: 30px;
    height: 30px;
    background-color: orange;
}
.leftBtn{left: 10px;}
.rightBtn{right: 10px;}
.circls{
    position: absolute;
    bottom: 10px;left: 100px;
    list-style: none;
}
.circls li{
    float: left;
    width: 20px;
    height: 20px;
    background-color: orange;
    margin-right: 10px;
}
.circls li.cur{background-color: red;}

 

(function(){
    //強行暴露一個變數,一枝紅杏出牆來
    window.Carousel = Carousel;
    //輪播圖類
    function Carousel(JSON){
        this.$dom = $("#" + JSON.id); //DOM元素
        this.$imagesUl = null;
        this.$imagesUlLis = null;
        this.width = JSON.width;
        this.height = JSON.height;
        this.$leftBtn = null;
        this.$rightBtn = null;
        this.$circleOl = null;
        this.$circleLis = null;
        this.interval = JSON.interval;
        this.speed = JSON.speed; //滑動速度
        this.idx = 0;//信號量
        this.imagesURLArr = JSON.images;//圖片地址數組
        this.pictureLength = JSON.images.length;//圖片長度
        this.init();
        this.bindEvent();
        this.autoPlay(); //定時器
    }
    //初始化DOM
    Carousel.prototype.init = function(){
        //創建ul節點
        this.$imagesUl = $("<ul></ul>");
        this.$dom.append(this.$imagesUl);
        //創建li節點
        for(var i = 0; i < this.pictureLength; i++) {
            $("<li><img src='"+this.imagesURLArr[i].picurl+"'/></li>")
.appendTo(this.$imagesUl);
        };
        //獲得li元素引用
        this.$imagesUlLis = this.$imagesUl.find("li");
        //大盒子的佈局
        this.$dom.css({
            "width" : this.width,
            "height" : this.height,
            "position" : "relative",
            "overflow" : "hidden"
        });
        //貓膩,讓所有li藏起來(left移動到顯示區域外)
        this.$imagesUlLis.css({
            "position" : "absolute",
            "left": this.width,
            "top": 0
        });
    //只顯示第一張圖
        this.$imagesUlLis.eq(0).css("left",0);
        //創建按鈕
        this.$leftBtn = $("<a href='javascript:;' class='leftBtn'></a>");
        this.$rightBtn = $("<a href='javascript:;' class='rightBtn'></a>");
        this.$leftBtn.appendTo(this.$dom);
        this.$rightBtn.appendTo(this.$dom);
        //創建小圓點
        this.$circleOl = $("<ol class='circls'></ol>");
        this.$circleOl.appendTo(this.$dom);
        for (var i = 0; i < this.pictureLength; i++) {
            $("<li></li>").appendTo(this.$circleOl);
        };
        //獲得ol的li元素
        this.$circleLis = this.$circleOl.find("li");
        //加cur
        this.$circleLis.eq(0).addClass("cur");
    }
})();

 

事件監聽方法:

Carousel.prototype.bindEvent = function(){
    var self = this;
    //右邊按鈕的監聽
    this.$rightBtn.click(function(){
        if(self.$imagesUlLis.is(":animated")) return;
        self.showNext();
    });
    //左邊按鈕的監聽
    this.$leftBtn.click(function(){
        if(self.$imagesUlLis.is(":animated")) return;
        self.showPrev();
    });
}

 

 showNext() 顯示下一張方法

//展示下一張
Carousel.prototype.showNext = function(){
    this.$imagesUlLis.eq(this.idx).animate({"left" : -this.width},this.speed);
    this.idx++;
    if(this.idx > this.pictureLength - 1){
        this.idx = 0;
    }
    this.$imagesUlLis.eq(this.idx).css("left",this.width).animate({"left" : 0},this.speed);
    //圓點的cur
    this.changeCirclesCur();
}

 

 changeCirclesCur()小圓點方法

Carousel.prototype.changeCirclesCur = function(){
    this.$circleLis.eq(this.idx).addClass("cur").siblings().removeClass("cur");
}

 

 showPrev() 顯示上一張方法

//展示上一張
Carousel.prototype.showPrev = function(){
    this.$imagesUlLis.eq(this.idx).animate({"left" : this.width},this.speed);
    this.idx--;
    if(this.idx < 0){
        this.idx = this.pictureLength - 1;
    }
    this.$imagesUlLis.eq(this.idx).css("left",-this.width).animate({"left" : 0},this.speed);
    //圓點的cur
    this.changeCirclesCur();
}
//自動輪播
Carousel.prototype.autoPlay = function(){
    var self = this;
    this.timer = setInterval(function(){
        self.showNext();
    },this.interval);
}

 

bindEvent()

Carousel.prototype.bindEvent = function(){
    var self = this;
    //滑鼠停表
    this.$dom.mouseenter(function(){
        clearInterval(self.timer);
    });
//離開開啟
    this.$dom.mouseleave(function(){
        self.autoPlay();
    });
//圓點的監聽
this.$circleLis.click(function(){
    self.show($(this).index());
});
}
//小圓點點擊展示任意
Carousel.prototype.show = function(number){
    var old = this.idx; //舊idx信號量
    this.idx = number;    //當前點擊的信號量,改變全局
    //判斷
    if(this.idx > old){ //從右到左
        this.$imagesUlLis.eq(old).animate({"left" : -this.width},this.speed);
        this.$imagesUlLis.eq(this.idx).css("left",this.width).animate({"left" : 0},this.speed);
    }else if(this.idx < old){//從左到右
        this.$imagesUlLis.eq(old).animate({"left" : this.width},this.speed);
        this.$imagesUlLis.eq(this.idx).css("left",-this.width).animate({"left" : 0},this.speed);
    }
    //圓點的cur
    this.changeCirclesCur();
}

二、俄羅斯方塊游戲開發

2.1先認識方塊

俄羅斯方塊一共有7種:SZJLOIT

2.2寫二維數組的JSON表(表示磚塊)

首先做兩種圖形:

// S Z J L O I T

var block_json = {
    "I":[ //I有2種方向
        [
            [0,1,0,0],
            [0,1,0,0],
            [0,1,0,0],
            [0,1,0,0]
        ],
        [
            [0,0,0,0],
            [0,0,0,0],
            [1,1,1,1],
            [0,0,0,0]
        ]
    ],
    "L":[ //L有4種方向
        [
            [0,1,0,0],
            [0,1,0,0],
            [0,1,1,0],
            [0,0,0,0]
        ],
        [
            [1,1,1,0],
            [1,0,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [1,1,0,0],
            [0,1,0,0],
            [0,1,0,0],
            [0,0,0,0]
        ],
        [
            [0,0,1,0],
            [1,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ]
    ],
    "J":[//J有4種方向
        [
            [0,1,0,0],
            [0,1,0,0],
            [1,1,0,0],
            [0,0,0,0]
        ],
        [
            [1,0,0,0],
            [1,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [1,1,0,0],
            [1,0,0,0],
            [1,0,0,0],
            [0,0,0,0]
        ],
        [
            [1,1,1,0],
            [0,0,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ]
    ],
    "O":[ //O有1種方向
        [
            [1,1,0,0],
            [1,1,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ]
    ],
    "Z":[ //Z有2種方向
        [
            [1,1,0,0],
            [0,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,0,1,0],
            [0,1,1,0],
            [0,1,0,0],
            [0,0,0,0]
        ]
    ],
    "S":[ //S有2種方向
        [
            [0,1,1,0],
            [1,1,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,1,0,0],
            [0,1,1,0],
            [0,0,1,0],
            [0,0,0,0]
        ]
    ],
    "T":[//T有4種方向
        [
            [1,1,1,0],
            [0,1,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,1,0,0],
            [1,1,0,0],
            [0,1,0,0],
            [0,0,0,0]
        ],
        [
            [0,1,0,0],
            [1,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,1,0,0],
            [0,1,1,0],
            [0,1,0,0],
            [0,0,0,0]
        ]
    ]
}
數組圖形

 

2.3基本佈局【table表格(12*20)】

都是套路,和貪吃蛇沒區別。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
        table{
            margin:50px auto;
        }
        table,tr,td{border: 1px solid #000;border-collapse:collapse;}
        td{width: 18px;height: 18px;}
    </style>
</head>
<body>
    <div id="app"></div>
</body>
<script type="text/javascript" src="js/Game.js"></script>
<script type="text/javascript" src="js/Block.js"></script>
<script type="text/javascript">
    var game = new Game()
</script>
</html>

迴圈創建12*20table表格,原因:為了方塊能居中。

(function(){
    window.Game = function(){
        this.init()
    }

    //20 * 12創建表格
    Game.prototype.init = function(){
        this.dom = document.createElement('table');
        document.getElementById("app").appendChild(this.dom);

        var tr,td;
        //迴圈插入行
        for(var i = 0;i < 20;i++){
            tr = document.createElement('tr');
            this.dom.appendChild(tr);
            for(var j = 0;j < 12;j++){
                //迴圈插入列
                td = document.createElement('td');
                tr.appendChild(td);

            }
        }
    }
})();
//如果別的類修改Game類的表格顏色,儘量提供一個方法給其他類調用,不要讓其他類修改自己的屬性
//設置table表格的顏色
Game.prototype.setClass = function(row, col, classname){
    this.dom.getElementsByTagName('tr')[row].getElementsByTagName('td')[col].className = 
classname
}

 

index.html中寫兩個類:

.L{background: skyblue;}
.I{background: pink;}

(function(){
    window.Block = function(){
        //在所有的形狀中,選擇一個磚塊形狀
        var arr = ["I","L","J"];
        this.allType = arr[~~(Math.random() * arr.length)]
        console.log(this.allType)
        //自己所有的方向個數
        this.allDirectionNumber = block_json[this.allType].length;
        //隨意一個方向
        this.direction = ~~(Math.random() * this.allDirectionNumber);

        //得到形狀,馬上渲染圖形的而進行code碼
        this.code = block_json[this.allType][this.direction];

        //4 * 4小方塊的初始位置
        this.row = 0;
        this.col = 4; //保證方塊從中間出現
    }
})();


2.4磚塊渲染

(function(){
    window.Block = function(){
         ...
    }

    //渲染磚塊
    Block.prototype.render = function(){
        for(var i = 0; i < 4;i++){
            for(var j = 0; j < 4;j++){
                //顯示4 * 4矩陣顏色,寫class類
                game.setClass(this.row + i, this.col + j, "gray");
                if(this.code[i][j] == 1){
                    //如果4 * 4 二維數組編碼中有1就渲染顏色,0就沒色
                    game.setClass(this.row + i, this.col + j, this.allType)
                }
            }
        }
    }
})();

 

別忘記在Game類中添加定時器並render block(渲染方塊)

(function(){
    window.Game = function(){
        this.init();
        this.start();
        //實例化磚塊類
        this.block = new Block();
    }

    Game.prototype.start = function(){
        var self = this;
        setInterval(function(){
            //渲染磚塊
            self.block.render();
        },30);
    }
})();


2.5磚塊下落

//磚塊下落
Block.prototype.down = function(){
    this.row++;
}

//清屏方法
Game.prototype.clearClass = function(){
    for(var i = 0; i < 20;i++){
        for(var j = 0; j < 12;j++){
            game.setClass(i, j, "");
        }
    }
}
Game.prototype.start = function(){
    this.f = 0;
    var self = this;
    setInterval(function(){
        self.f++;
        //清屏
        self.clearClass()
        //渲染磚塊
        self.block.render();
        //每間隔20幀下落
        self.f % 20 == 0 && self.block.down();
    },30);
}

磚塊就能下落了


2.6 Map地圖類

Map地圖類存儲死亡的方塊

(function(){
    window.Map = function(){
        this.code = [
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0]
        ]
    }
})()
地圖

for迴圈更優雅的創建二維數組

this.code = (function(){
    var arr = [];
    for(var i = 0;i < 20;i++){
        arr.push([]);
        for(var j = 0;j < 12;j++){
            arr[i].push(0)
        }
    }
    return arr;
})();

 

ES6語法,寫一個二維數組:

new Array(20).fill(new Array(12).fill(0)
(function(){
    window.Map = function(){
        this.code = (function(){
            var arr = [];
            for(var i = 0;i < 20;i++){
                arr.push([]);
                for(var j = 0;j < 12;j++){
                    arr[i].push(0)
                }
            }

            //寫一個“一柱擎天”方便測試
            arr[10][5] = "L";
            arr[11][5] = "L";
            arr[12][5] = "L";
            arr[13][5] = "L";
            arr[14][5] = "L";
            arr[15][5] = "L";
            arr[16][5] = "L";
            arr[17][5] = "L";
            arr[18][5] = "L";
            arr[19][5] = "L";

            return arr;
        })();

        console.log(this.code)
    }
})()

 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這是我的第一篇博客,務必請大家多多關照。 下麵是前端js的變數和數據類型的一些筆記,不是很全請多多包涵。 1.變數 變數的聲明 var 變數名 變數這個容器中放的是數據 變數的賦值 變數名 = 數據 var a; a = 123; 聲明 和 賦值 合併 var b = 123; 變數的連續聲明 va ...
  • 1、年份(1970-) 獲取 date.getFullYear(); 設置 date.setFullYear(2016); 2、月份(0-11) 0代表1月 獲取 date.getMonth() 設置 date.setMonth(0);//設置月份為1月 3、日(1-31) 獲取 date.getD ...
  • 好久沒寫一些東西了,總是感覺有啥缺少的。~~~~恰好碰到最近在寫一個移動端項目,遇到瞭如何使同一個鏈接在不同條件下跳轉到不同路由組件問題,譬如大家經常看到手機中沒登錄跳轉登錄頁,登陸後跳轉個人信息頁等。廢話不多說了,直接上圖: 這是沒登錄狀態,點擊下麵mine按鈕跳轉至登錄頁 這個是我登錄了自己的賬 ...
  • 微信小程式報錯 Unexpected end of JSON input;at pages/flow/checkout page getOrderData function 這個報錯是在將數組對象通過頁面傳值,傳到指定頁面時報的錯。 是因為JSON.parse無法識別某些url中的特殊字元,所以報錯 ...
  • 實現方法用 formatter 但是在click中傳參中遇到一個問題 點擊a時瀏覽器的控制台報錯 最後百思不得其姐一會終於解決了,傳參時轉義一下就好了,如下圖 ...
  • 公司有個項目要實現一個聊天功能,需求如下圖,略顯隨意 公司最終選擇融雲這個弔炸天的即時通信,文檔詳細的一匹,剛開始看文檔感覺很詳細實現起來也不麻煩,有很多開源的demo可以線上演示和下載 不過我們的項目是vue cli創建的,文檔就沒這個了,網羅了一堆博客也有說vue使用的不過都不是很齊全 就總結了 ...
  • 參考資料:獲取時長 自己留個筆記。 ...
  • 一、Canvas基本使用 Canvas是HTML5的畫布,Canvas算是“不務正業”的面向對象大總結,將面向對象玩極致。 演算法為王!就是說canvas你不會,但是演算法好,不怕寫業務,不怕代碼量,只要稍微學學API就能出活。 Canvas這裡是HTML5新標簽,直接要了flash的命。 1.1 Ca ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...