模仿igoogle【定制化、拖动排序,最大化、分屏】
【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() + '" >数据加载中......</div></fieldset>' ;
$main.hide();
$max.show();
$title.html(title);
if (type && type == "s-html" ) {
var html = '<iframe scrolling="no" 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" 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);
}
//---------------------------------------------------------------------------
代码太多不做说明了,以后肯定会封装,
就现在看来整个应用感觉问题不少,实际用处不大吧。
后面点代码整理后再一并发出吧,如果有需要的话。
Web前端
【jquery仿dataList】应用之——模仿igoogle【定制化、拖动排序,最大化、分屏】
posted @ 2012-03-07 22:34 叶小钗 阅读(1221) | 评论 (25) 编辑
【jquery版.net控件—dropdownlist】附源码,欢迎大家指点、指正、拍砖!!!
posted @ 2012-02-10 01:04 叶小钗 阅读(1760) | 评论 (17) 编辑
【jquery模仿net控件】简单的datalist控件更新,及其简单应用
posted @ 2012-01-25 22:32 叶小钗 阅读(1531) | 评论 (1) 编辑
【jquery模仿net控件】简单的dropdownlist与datalist
posted @ 2012-01-22 02:24 叶小钗 阅读(2021) | 评论 (6) 编辑
javascript01-div居中的兼容问题,发一个奇怪的代码,可能是我没有理解精髓吧。
posted @ 2011-11-24 13:52 叶小钗 阅读(559) | 评论 (4) 编辑
只言碎语总结,今后发展web前端,并分享两个项目难点解决方案。
posted @ 2011-10-07 14:25 叶小钗 阅读(3589) | 评论 (46) 编辑
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于模仿igoogle【定制化、拖动排序,最大化、分屏】的详细内容...