javascript設計模式_享元模式

享元模式:避免對象間用用相同內容造成多餘的開銷。

例如一個簡單的新聞翻頁功能,頁面加載後,異步請求新聞數據,然後創建所有條新聞並插入頁面中,需要顯示哪一頁就將對應頁的新聞顯示,其他的新聞隱藏......

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>javascript設計模式_享元模式</title>
    <style>
        .container div{
            width: 200px;
            height: 80px;
            line-height: 80px;
            background-color: gray;
            color: white;
            margin-bottom: 20px;
        }
    </style>

    <script>
        // article爲獲取到的數據
        var article=["我是文章內容的標題1","我是文章內容的標題2","我是文章內容的標題3","我是文章內容的標題4","我是文章內容的標題5",
        "我是文章內容的標題6","我是文章內容的標題7","我是文章內容的標題8","我是文章內容的標題9","我是文章內容的標題10","我是文章內容的標題11","我是文章內容的標題12",
        ];
        window.onload=function(){
            // oldFun();
            newFun();
        }
        
        function oldFun(){

            var dom = null,//緩存創建的新聞標題元素
            paper = 0,//當前頁數
            num = 5, //每頁顯示新聞數目
            i = 0,//創建新聞元素時保存變量
            len = article.length; //新聞數據的長度

            for(;i<len;i++){
                dom=document.createElement('div');//創建包裝新聞標題元素
                dom.innerHTML=article[i];//向元素中添加新聞標題
                if(i>=num){
                    dom.style.display='none';//超出第一頁新聞隱藏
                }
                document.getElementById('container').appendChild(dom);//添加到頁面中
            }

            //下一頁事件綁定
            document.getElementById('nextPage').onclick=function(){
                var div=document.getElementById('container').getElementsByTagName('div');//獲取所有新聞標題
                var j=k=n=0;//j、k循環變量,n當前頁顯示的第一個新聞序號
                n=++paper%Math.ceil(len/num)*num;//獲取當前頁顯示的第一個新聞序號
                for(;j<len;j++){
                    div[j].style.display='none';//隱藏所有新聞
                }
                for(;k<5;k++){
                    if(div[n+k]){
                        div[n+k].style.display="block";//顯示當前頁新聞
                    }
                }
            }
        }
    
        function newFun(){
            //創建一個操作函數
            var flyWeight=function(){
                var created=[];//存儲已創建的元素的數組
                return {
                    getDiv:function(){
                        if(created.length<5){//當元素不足5個這種基本條件的時候,通過create()函數繼續新建一個dom節點
                            return create();
                        }else{//否則,複用數組中的dom節點
                            var div=created.shift();//獲取最後一個元素
                            created.push(div);//插入到最後面
                            return div;//返回重新編排的元素節點
                        }
                    }
                }
                function create(){ //用於頁面初始化時創建元素的函數
                    var dom=document.createElement('div');
                    document.getElementById('container').appendChild(dom);//將容器插入新聞列表容器中
                    created.push(dom);//存到已創建元素數組中
                    return dom;//返回新創建的元素節點
                }
            }();//注意,立即執行!

            var page=0,//當前頁數
            num=5,//一頁顯示條目數
            len=article.length;//數據長度
            for(var i=0;i<5;i++){
                if(typeof(article[i])!=undefined){//如果有數據
                    flyWeight.getDiv().innerHTML=article[i];//通過享元函數寫入數據內容
                }
            }
            document.getElementById('nextPage').onclick=function(){
                if(article.length<5){
                    return;//數據小於基本要求5條,不執行操作
                }else{
                    var n=++page*num%len;//獲取當前頁第一條新聞的下標
                    for(var j=0;j<5;j++){
                        if(article[n+j]){//如果大於5條之後還有數據
                            flyWeight.getDiv().innerHTML=article[n+j];//通過享元函數寫入數據內容
                        }
                        else if(article[n+j-len]){
                            flyWeight.getDiv().innerHTML=article[n+j-len];//如果第N頁不夠5條,從頭開始補上
                        }
                        else{
                            flyWeight.getDiv().innerHTML=" ";
                        }
                    }
                }
            }
        }

    </script>


</head>
<body>
    <div id="container" class="container">
        <p>顯示新聞</p>
        <button id="nextPage">下一頁</button>
    </div>
    
</body>
</html>

所有的新聞都有相同的結構,只是內容不同,創建幾百條新聞同時插入頁面並造成的多餘的開銷在低版本的瀏覽器中會嚴重影響其性能

對於相同結構造成的多餘的開銷問題,可以使用享元模式解決。

主要對其數據、方法共享分離,將其數據和方法分爲內部數據、內部方法和外部數據、外部方法。將內部數據與內部方法中相似或共有的數據和方法提取出來減少開銷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章