【jquery仿dataList】應用之——模仿igoogle【定制化、拖動排序,最大化、分屏】


接上一次日志哈,這一次用原來寫的datalist實現了簡單應用,模擬igoogle。

做的過程中發現代碼很多問題,主要是流程上的問題。

主要是自己層次不夠,明明已經感到這樣那樣的問題,都能說出來就是不知道怎么改。主要問題:

1 初始化時候參照其他jquery框架,應該達到配置最小化,卻怎么都做不好

2 現在控件必須提供數據源datalist與模板template,數據源還好說,但是模板的寫法真的太坑爹,現在是放在數據庫里面了

以后怎么做還說不清哦

3 與.net中datalist一致,不論datalist還是item都會生成多余的標簽,這里是生成的div,看上去很是別扭

4 最大問題還是,混亂!!!就像這篇文章一樣,js控制力不同於服務器語言,所有整個做起來,不論事件綁定

還是其他什么定義都感覺有點混亂,流程不清,這是我主要應該改進的地方。


主要流程:

1 加載小工具模板:現在先一次性加載,以后用到一個保存一個作為全局參數
2 加載該用戶的所有小工具:現在先一次性加載,以后先加載第一頁,
根據頁索引判斷加載
3 根據用戶小工具數據,初始化所有小工具外框
由於數據以及模板已經取出,此時加載速度應該非常快,左中右一次加載
**此處注意,雖說小工具外框一樣,但是新增的小工具可能會在外框加載結束后再修飾外框
比如,weibo、top.....,此數據存於小工具定制列(CustomData)
4 此時進行數據異步加載,
***數據可以統一加載,但是此處先加載所有小工具每列前兩名數據
在根據后台用戶干預加載那些大數據小工具,加載結束后,當用戶滑動鼠標便進行以下
控件加載,每次控件加載數量可配置化
5 所有控件加載結束,已加載結束控件,可能會根據后台配置要求動態刷新數據
此處需要做輪詢
6 控件加載結束后,開始做控件事件綁定
***注意粒度盡量小,不要和其他模塊相互影響


首頁效果圖:

此處點擊都會觸發事件,一個是異步加載選項卡數據,一個是展開摘要:

也可以延后加載,比如:開始只加載前三個模塊,鼠標滑動后,再加載后面的模塊:

一下是,初始化后鼠標滑動前與鼠標滑動后的效果:

 


分屏、分頁效果

點擊上面1,2,3肯定會指向不同也了,其實現在用戶是我,若是用戶換了也會有所不同

下面是第二頁和第三頁


拖動排序也實現了,之前想自己寫一個拖動插件,拖動時實現了卻發現插件非常困難,

局限於自己的層次,就直接用的jquery ui的拖動

下面是拖動排序的展示,保存到數據庫的,最后一張是刷新后重新排序的圖:


點擊最大化,並實現鼠標滾動到最下邊重新加載數據(滾動分頁嘛):

 


數據庫簡要設計,因為我沒有安裝數據庫,所有優點不好弄:

設計緣由:由於今后可能不止五頁,做到頁數動態化

 

NO.

字段名稱

說明

1

uuid

頁面唯一標識

2

pageSort

頁面排序

3

pageName

頁面標題,默認1,2,3,4,5

4

pageDes

頁面描述,鼠標划上顯示

5

 

 

 

小工具模板表 templates(基本字段)

 

NO.

字段名稱

說明

1

uuid

頁面唯一標識

2

templateKey

標識

3

templateValue

模板內容

4

des

描述

5

 

 

 

 

 

小工具表 modules(基本字段)

小工具參數化,可變參數,具有驗證性

 

NO.

字段名稱

說明

1

uuid

小模塊唯一標識

 

author

小工具作者

2

alias

模塊前台標識名,對應category

3

title

小模塊名稱

4

dataSourceUrl

數據源鏈接地址

5

pageId

當前小工具屬於第幾屏,對應pages 的 uuid

6

colId

當前小工具屬於第幾列(暫分為1,2,3列)

7

sort

當前小工具順序

8

templateId

當前小工具對應模板,對應templates表

9

type

當前小工具類型,frame或者json

 

 

 

 

 

 

 

參數化后

NO.

字段名稱

說明

1

uuid

小模塊唯一標識

2

alias

模塊前台標識名,對應category

3

title

小模塊名稱

5

pageId

當前小工具屬於第幾屏,對應pages 的 uuid

6

colId

當前小工具屬於第幾列(暫分為1,2,3列)

7

sort

當前小工具順序

8

moduleParameter

當前小工具具有的參數對象,現在采用json對象

采用鍵值對,加一個描述字段

{dataSourceUrl:XXXXX ,templateId:XXXX , type:XXX }

以上是基本屬性,應該是字段吧…..

灰色部分可以不用,直接默認在第一頁第一排,默認最大

其默認值在用戶小工具表中體現出來

 

 

小工具參數moduleParameter

 

NO.

字段名稱

說明

1

uuid

小模塊唯一標識

2

moduleKey

 

3

moduleValue

 

4

des

 

5

isTransfer

是否形成json傳向前台

 

 

 

 

 

 

 

用戶小工具設置表(用戶參數設置)

userModules

NO.

字段名稱

說明

1

uuid

小模塊唯一標識

2

userId

用戶id

3

moduleId

小工具Id

 

userPrefers

用戶偏好設置

 

 

 

 

 

 

用戶小工具參數偏好userModulePre

 

NO.

字段名稱

說明

1

uuid

小模塊唯一標識

2

preKey

 

3

preValue

 

4

des

 

5

isTransfer

是否形成json傳向前台

 

 

 

 

 

最終表設計


核心實現代碼如下:原來的datalist的代碼我就不發了:

 

/// <reference path="../scripts/jquery-1.4.1.js" />
/// <reference path="dataList.js" />
/// <reference path="itemTemplate.js" />
//全局變量設置
var templateWarehouse = {};
var userModuleData = {};
var leftColModule, centerColModule, rightColModule;
//首頁模塊加載參數
var moduleLoadPara = {};
moduleLoadPara.index = 1; //初始化加載索引
moduleLoadPara.num = 1; //每次索引加載個數
moduleLoadPara.isLoad = false; //當前是否在加載
//---------------------------------------------------------------------------
//第一步,加載模板
function loadTemplate() {
    $.ajax({
        type: "post",
        url: "../Ajax.aspx?sql=select * from templates ",
        type: "json",
        async: false,
        success: function (data) {
            $.each(data, function (i, item) {
                templateWarehouse[item.templateKey] = item.templateValue;
            });
        }
    });
}
//加載所有模板數據
function loadModuleData(isAsync) {
    var _isAsync = false;
    if (isAsync)
        _isAsync = isAsync;
    var userId = "wl";
    $.ajax({
        type: "post",
        url: "../Ajax.aspx?sql=select * from modules m ,userModules um where 1=1 and m.uuid=um.moduleId and um.userId='" + userId + "'",
        type: "json",
        async: _isAsync,
        success: function (data) {
            userModuleData["1"] = [];
            userModuleData["2"] = [];
            userModuleData["3"] = [];
            userModuleData["4"] = [];
            userModuleData["5"] = [];
            $.each(data, function (i, item) {
                var userPrefs = item.userPrefers;
                if (typeof (userPrefs) == "string") {
                    userPrefs = eval("(" + userPrefs + ")"); ;
                }
                item.userPrefers = userPrefs;
                userModuleData[userPrefs.pageId].push(item);
            });
        }
    });
}
//---------------------------------------------------------------------------
//根據用戶id,按要求加載其模板
function initModuleFrame(_pageId) {
    var pageId = 1;
    if (_pageId)
        pageId = _pageId;
    var $div = $("#main");
    $div.html("");
    loadColModule(pageId, "left_conter");
    loadColModule(pageId, "cell_conter");
    loadColModule(pageId, "right_conter");
}
function loadColModule(pageId, colId) {
    var $div = $("#main");
    var colData = getColData(pageId, colId);
    var colModule = new dataList(colId, "commonFrame");
    colModule.itemElementEvent = {
        _sortItems: {
            elementKey: ".content",
            eventType: "ready",
            funcName: itemSort
        },
        _itemMaxClick: {
            elementKey: ".btn_close",
            eventType: "click",
            funcName: itemMaxClick
        },
        _itemMenuClick: {
            elementKey: ".btn_more",
            eventType: "click",
            funcName: itemMenuClick
        }
    };
    colModule.className = "column";
    colModule.dataSource = colData;
    colModule.dataBind($div);
    if (colId == "left_conter") {
        leftColModule = colModule;
    } else if (colId == "cell_conter") {
        centerColModule = colModule;
    } else if (colId == "right_conter") {
        rightColModule = colModule;
    }
}
function getColData(pageId, colId) {
    var tempData = [];
    var data = userModuleData[pageId];
    $.each(data, function (i, item) {
        var userPrefs = item.userPrefers;
        if (userPrefs.pageId == pageId && userPrefs.colId == colId) {
            tempData.push(item);
        }
    });
    tempData = tempData.sort(function (a, b) {
        if (a.userPrefers.sort < b.userPrefers.sort) {
            return -1;
        }
        if (a.userPrefers.sort > b.userPrefers.sort) {
            return 1;
        }
        return 0;
    });
    return tempData;
}
//---------------------------------------------------------------------------
function loadItemMax(sender, param, e, isClick) {
    var dataSourceUrl = param.dataSourceUrl;
    var templateId = param.templateId + "-max";
    var title = param.title;
    var type = param.type;
    var id = sender.id;
    var $max = $("#list-max");
    var $main = $("#main");
    var $content = $("#list-max #list-max-content");
    if (isClick)
        $content.html("");
    var $title = $("#list-max #list-max-title");
    var $itemList = $("#list-max .list");
    var $listMore = $("#list-max #list-max-more");
    var isLoad = $listMore.val();
    $listMore.val("-1");
    var len = $itemList.length;
    var _index = len + 1;
    var itemStr = '<fieldset  class="list"><legend><span class="index">page' + _index.toString() + '</span></legend><div id="itemContent' + _index.toString() + '" style=" margin:10px 10px 10px 10px;">數據加載中......</div></fieldset>';
    $main.hide();
    $max.show();
    $title.html(title);
    if (type && type == "s-html") {
        var html = '<iframe scrolling="no" style="width:100%;height:200px" frameborder="0" src="' + dataSourceUrl + '"></iframe>';
        $content.html(html);
    } else {
        $content.append(itemStr);
        $.ajax({
            type: "post",
            url: dataSourceUrl,
            type: "json",
            async: true,
            success: function (data) {
                var $itemContent = $("#list-max #itemContent" + _index.toString() + "");
                $itemContent.html("");
                var dataNews = data;
                if (typeof (dataNews) == "string") {
                    dataNews = eval("(" + data + ")"); 
                }
                var listMax = new dataList(id + "_max", templateId);
                listMax.dataSource = dataNews;
                listMax.dataBind($itemContent);
                $listMore.val("1");
            }
        });
    }
}
//小工具事件定義,小工具事件處理函數
function itemMaxClick() {
    var sender = this;
    var param = arguments[0];
    var e = arguments[1];
    loadItemMax(sender, param, e, true);
    $(document).unbind("scroll");
    $(document).bind("scroll", function (e) {
        var windowHeight = $(window).height();
        var windowScrollTop = $(window).scrollTop();
        var documentHeight = $(document).height();
        var $listMore = $("#list-max #list-max-more");
        var isLoad = $listMore.val();
        if ((windowHeight + windowScrollTop + 100) > documentHeight && isLoad == "1") {
            loadItemMax(sender, param, e);
        }
    });
}
//小工具事件定義,點擊出現菜單欄
function itemMenuClick() {
    var sender = this;
    var param = arguments[0];
    var e = arguments[1];
    //    alert("彈出菜單" + "--" + param.uuid1 + "--" + sender.id)
    var uuid = param.uuid1;
    var popupMenu = $("#popupMenu");

}
//定義小工具會用到的工具類
var moduleInitTool = {};
//適用於不同模板,若是有新模板,只需根據規范添加函數即可,工廠方法
moduleInitTool.jsonModule = function (sender, param, e) {
    var templateId = param.templateId;
    var id = param.uuid;
    var dataSourceUrl = param.dataSourceUrl;
    var $itemContent = sender.getItemElement(".content");
    if (dataSourceUrl) {
        moduleLoadPara.isLoad = false;
        $.ajax({
            type: "post",
            url: dataSourceUrl,
            type: "json",
            async: true,
            success: function (data) {
                $itemContent.html("");
                var dataNews = data;
                if (typeof (dataNews) == "string") {
                    dataNews = eval("(" + data + ")"); ;
                }
                var listItemNews = new dataList(id + "_news", templateId);
                listItemNews.itemElementEvent = {
                    clickTitle: {
                        elementKey: ".span2",
                        eventType: "click",
                        funcName: titleClick
                    }
                }
                listItemNews.dataSource = dataNews;
                listItemNews.dataBind($itemContent);
                //                if (sender.id == "right_conter_id_1")
                //                    setInterval(function () {
                //                        alert("重新加載" + sender.id);
                //                    }, 5000);
                moduleLoadPara.isLoad = true;
            }
        });
    }
}
moduleInitTool.htmlModule = function (sender, param, e) {
    var id = param.uuid;
    var dataSourceUrl = param.dataSourceUrl;
    var $itemContent = sender.getItemElement(".content");
    if (dataSourceUrl) {
        var html = '<iframe scrolling="no" style="width:100%;height:200px" frameborder="0" src="' + dataSourceUrl + '"></iframe>';
        $itemContent.html(html);
    }
}
moduleInitTool.weiboModule = function (sender, param, e) {

}
moduleInitTool.labelModule = function (sender, param, e) {
    var templateId = param.templateId;
    var id = param.uuid;
    var dataSourceUrl = param.dataSourceUrl;
    var customData = param.customData;
    var modulePara = param.moduleParameter;
    if (typeof (modulePara) == "string") {
        modulePara = eval("(" + modulePara + ")"); ;
    }
    templateWarehouse["labelHeadTemplate"] = modulePara.labelHeadTemplate;
    var $itemContent = sender.getItemElement(".content");
    $itemContent.html(customData);
    var lableHead = sender.getItemElement("#labelHead");
    moduleLoadPara.isLoad = false;
    $.getJSON("../Ajax.aspx?sql=select * from bigType", function (data) {
        var labelHeadList = new dataList(id + "_head", "labelHeadTemplate");
        labelHeadList.dataSource = data;
        labelHeadList.className = "labelHead";
        labelHeadList.itemEvent = {
            _labelHeadClick: {
                eventType: "click",
                funcName: function () {
                    var _sender = this;
                    var _param = arguments[0];
                    var _e = arguments[1];
                    var labelBody = sender.getItemElement("#labelBody");
                    var bigTypeId = _param.id;
                    var url = "../Ajax.aspx?sql=select * from smallType where bigTypeId=" + bigTypeId + "";
                    $.getJSON(url, function (_data) {
                        labelBody.html("");
                        var labelBodyList = new dataList(bigTypeId + "_head", templateId);
                        labelBodyList.dataSource = _data;
                        labelBodyList.dataBind(labelBody);
                    });
                }
            }
        };
        labelHeadList.dataBind(lableHead);
        moduleLoadPara.isLoad = true;
    });
}

function elementDatabind(s) {
    var sender = this;
    var param = arguments[0];
    var e = arguments[1];
    var type = param.type;
    if (type && type.length > 2) {
        var _funcName = type.substring(2) + "Module";
        //        eval(_funcName);//此方法不能異步調用
        var funcName = moduleInitTool[_funcName];
        if (funcName && typeof (funcName) == "function") {
            funcName(sender, param, e);
        }
    }
}

function titleClick() {
    var sender = this;
    var param = arguments[0];
    var e = arguments[1];
    var summary = sender.getItemElement(".summary");
    var isShow = summary.css("display");
    if (isShow == "none") {
        summary.show();
    } else {
        summary.hide();
    }
}
//用於小工具排序
function itemSort() {
    var sender = this;
    var html = sender.htmlElement;
//    alert(html.offset().top);
    $(".column").sortable({
        connectWith: ".column",
        cursor: 'move',
        opacity: 0.7,
        handle: " .title",
        stop: sortItemsAjax
    });
}
//向后台發送數據
function sortItemsAjax() {
    submitSortData("left_conter");
    submitSortData("cell_conter");
    submitSortData("right_conter");

}
function submitSortData(colId) {
    var parent = $("#" + colId);
    var $children = parent.children();
    $children.each(function (i, item) {
        var id = item.id;
        var itemId = "#" + id + " #itemId";
        var $uuid = $(itemId);
        var uuid = $uuid.html();
        var userPrefers = item.userPrefers;
        $.ajax({
            type: "post",
            url: "../Ajax.aspx?sort=" + i + "&colId=" + colId + "&id=" + uuid + "&no=no",
            type: "json",
            async: true,
            success: function (data) {
            }
        });

    });
}
//---------------------------------------------------------------------------
//總體外部流程,外部方法
function mainProcess() {
    var $max = $("#list-max");
    var $main = $("#main");
    var $btn_Narrow = $("#list-max .btn_Narrow");
    $btn_Narrow.unbind("click");
    $btn_Narrow.bind("click", function () {
        if ($max.css("display") == "none") {
            $main.hide();
            $max.show();
        } else {
            $(document).unbind("scroll");
            var $listMore = $("#list-max #list-max-more");
            $listMore.val("-1");
            $main.show();
            $max.hide();
        }
    });
}


function LaterEvent() {
    var commomEvent = {
        _loadItems: {
            elementKey: ".content",
            eventType: "ready",
            funcName: elementDatabind
        }
    };
    var num = (moduleLoadPara.index) * (moduleLoadPara.num);
    for (var i = 0; i < num; i++) {
        if (leftColModule.items[i])
            leftColModule.items[i].eventAdd(commomEvent);
        if (centerColModule.items[i])
            centerColModule.items[i].eventAdd(commomEvent);
        if (rightColModule.items[i])
            rightColModule.items[i].eventAdd(commomEvent);
    }
    moduleLoadPara.index++;
    
    //    leftColModule.eventAdd(commomEvent);
    //    centerColModule.eventAdd(commomEvent);
    //    rightColModule.eventAdd(commomEvent);
}
function delayLoad() {
    var commomEvent = {
        _loadItems: {
            elementKey: ".content",
            eventType: "ready",
            funcName: elementDatabind
        }
    };
    $(document).unbind("scroll");
    $(document).bind("scroll", function (e) {
        if (moduleLoadPara.isLoad) {
            var num = (moduleLoadPara.index) * (moduleLoadPara.num);
            var oldNum = (moduleLoadPara.index-1) * (moduleLoadPara.num);
            for (var i = oldNum; i < num; i++) {
                if (leftColModule.items[i])
                    leftColModule.items[i].eventAdd(commomEvent);
                if (centerColModule.items[i])
                    centerColModule.items[i].eventAdd(commomEvent);
                if (rightColModule.items[i])
                    rightColModule.items[i].eventAdd(commomEvent);
            }
            moduleLoadPara.index++;
        }
    });
}
function pageClick() {
    for (var i = 1; i <= 5; i++) {
        var page = $("#pageIndex" + i.toString());
        page.unbind("click");
        page.bind("click", function (e) {
            var _p = $(this);
            initModuleFrame(_p.text());
            LaterEvent();
            var $max = $("#list-max");
            var $main = $("#main");
            $main.show();
            $max.hide();
            $(document).unbind("scroll");
            var $listMore = $("#list-max #list-max-more");
            $listMore.val("-1");
            //置頂
            $('html,body').animate({ scrollTop: '0px' }, 800);
            //            A:return false --->In event handler ,prevents default behavior and event bubbing 。
            //return false 在事件的處理中,可以阻止默認事件和冒泡事件。
            //B:event.preventDefault()---> In event handler ,prevent default event (allows bubbling) 。
            //event.preventDefault()在事件的處理中,可以阻止默認事件但是允許冒泡事件的發生。
            //C:event.stopPropagation()---> In event handler ,prevent bubbling (allows default behavior).
            //event.stopPropagation()在事件的處理中,可以阻止冒泡但是允許默認事件的發生。
            e.stopPropagation();
            return false;
        });
    }
}
function pageLoad() {
    mainProcess();
    loadTemplate();
    loadModuleData();
    initModuleFrame();
     
    LaterEvent();
    pageClick();
    //置頂
    $('html,body').animate({ scrollTop: '0px' }, 800);
    delayLoad();

    //5分鍾更新一次模塊數據
    var updateModuleData = setInterval("loadModuleData(true)", 50000);

}
//---------------------------------------------------------------------------

 

  

 


代碼太多不做說明了,以后肯定會封裝,

就現在看來整個應用感覺問題不少,實際用處不大吧。

后面點代碼整理后再一並發出吧,如果有需要的話。

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM