您的位置:首页 > Web前端 > JQuery

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

2013-06-24 10:59 369 查看
接上一次日志哈,这一次用原来写的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);

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


  

代码太多不做说明了,以后肯定会封装,

就现在看来整个应用感觉问题不少,实际用处不大吧。

后面点代码整理后再一并发出吧,如果有需要的话。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: