首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

[转]博客个人化定制-实现类似iGoogle首页功能

2012-10-29 
[转]博客个性化定制-实现类似iGoogle首页功能最近在忙几个事,工作上做天河部落的升级改版,绕有兴致的做博

[转]博客个性化定制-实现类似iGoogle首页功能

最近在忙几个事,工作上做天河部落的升级改版,绕有兴致的做博客的个性化功能,以前我的博客也有几个样式模板,但是模块没有定制,昨天顺便就把我博客的个性化定制功能实现了,对于Asp.Net的博客个性化定制功能的方法总结如下:

1.简单的切换css样式文件

这是我之前的博客切换风格的方法,很简单,只需要改变页面的一个css样式文件即可,通过换css样式文件页面也完全可给人耳目一新,但其页面的html结构并没有发生改变,所以就不可能从根本上实现博客个性化定制,换换皮肤而已。我之前是使用javascript来改变css文件路径的,有时候加载样式很慢的情况下,在切换样式的那一瞬间页面可能会出现“裸奔”,也就是没有任何样式,这一点IE处理得很好,因为IE内可以预载css样式,在更换css样式文件的时候它会先预载新的css样式文件,完成之后才会被附加到页面来,所有不会出现上面的“裸奔”情况。然而在表扬IE的时候又想起之前碰到IE7里面的一个潜规则:在使用javascript更换css样式文件的时候不会加载样式文件内联的@import url(..)样式。适应它潜规则的方法是:先指定一个空路径再设置为样式文件路径即可,如下:

<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->document.getElementById('currSkin').href = '';document.getElementById('currSkin').href = skinsrc;

2.切换博客的MasterPage.master母版页

假如你的博客是用Asp.Net母版页的话,并且博客前台页面都使用同一个母版页,那么你可以在所有Page基类的OnPreInit方法里更换MasterPage母版页以实现博客个性化功能。

<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->protected override void OnPreInit(EventArgs e){    base.OnPreInit(e);    //更换母版页    if (!string.IsNullOrEmpty(this.CurrentUser.Template.MasterPageSrc))    {        this.MasterPageFile = this.CurrentUser.Template.MasterPageSrc;    }}

此种方法虽然可以最大限度的改变博客模板,甚至是每个模板内的html可截然不同,但它同样有很大制约。因为MasterPage母版页并不能当成是模板,MasterPage母版页里面可能还有一些需要处理的逻辑,所以每个MasterPage母版可能需要对应一个cs类,如果里面所有的控件都是一样的话可以使用同一个CodeFile文件。但单更换MasterPage母版页还并不能定制博客模块,比如设置博客某些模块的位置或是否显示等,则还需要使用下面的动态加载ascx控件模块。

3.动态加载ascx控件模块

基于Asp.Net的强大控件功能,可使用服务器控件动态加载用户控件,而每一个用户控件都对应一个模块,比如个人档案、日历等等,用户可以在后台定制这些模块是否显示,显示位置等。我的博客个性化功能是使用MasterPage母版页结合动态加载ascx控件模块,我所定制的模块都是在MasterPage母版页里动态加载的,因为相册和留言等内页同样也是应用了同一个MasterPage母版页,所以定制的模块同样应用于所有内页。我们可以把相册或留言也作为一个模块,只不过在相册页面里相册模块是固定会要加载的。另外我这里还有一个版面设置,它其实是每一个模块都有的几种页面布局,假如版面是左-中的话那其实是只加载用户设置在左栏和中栏的模块,同时隐藏掉右栏;同理版面左-中-右则加载左栏、中栏、右栏的模块,中-右则加载中栏、右栏的模块,同时隐藏掉左栏。每一个版面都应该配合css动态输出一个样式文件,以便适用该种版面的布局。

4.使用微软的WebParts个性化部件

早在学校的时候有研究过微软自带WebParts个性化部件,那时候觉得很牛B,可以拖来拖去自定义位置,还可以自定义设置一些样式属性。不过WebParts个性化部件还是有很大的局限性,就是必须使用他那套成员资格、配置文件、角色管理、个性化设置提供程序,sqlserver版的数据库可以直接使用aspnet_regsql.exe生成,但其他类型的数据库恐怕只有自己来实现他的Provide接口了,发这些功夫去研究实现还不如自己做一个。总之,此种实现方法的约束太大,不太适用与需求多变复杂的项目中。

目前我的博客个性化还缺一个功能,那就是自定义添加一个模块,就好比说我在那里看到了一个很漂亮的播放器,这时候我就可以自定义添加一个我的音乐盒模块,里面贴播放器的html代码内容,并同样可以设置显示位置等。其实在以前一个项目里实现过该功能,之所以没有在我博客加这个功能,那是因为如果我真在那里看到了一个漂亮的播放器,我会做成一个系统的模块,可以选择是否显示该模块,可能我的博客以后会添加更多的模块,暂不需要自定义模块。

?

?

继上一篇博客个性化定制功能后,今天我又花了足足一天时间,实现了使用js拖拽定制模块功能。主要包括三步:1.拖拽模块;2.计算坐标位置;3.完成拖拽,保存当前布局位置。

一、拖拽功能

如果只单实现简单的拖拽功能,那其实很简单,就只要注意拖拽时选中文本一些问题。由于我这里还拖拽有一些区域限制等,模块又都是从后台动态输出的,就做成一个函数类,可能实现出来就没那么通用了。拖拽的过程一般我们会用到几个事件:鼠标开始按下onmousedown事件,拖动事件onmousemove,松开鼠标完成拖拽事件onmouseup。对于几个DOM元素都有相同的事件,一般不需要每个DOM元素逐一添加事件监听,可以添加一个事件到它们公共的父元素上,这样感觉更好,然后通过事件的target或srcElement捕获触发事件源元素,这里的拖拽也是这样来实现的,onmousedown事件是监听拖拽模块的父容器元素,这个方法有点不好的就是可能获得事件发生源并不是你想要的,可能获得的是它的子元素,所以这里可能还需要额外加一个是否为parentNode的判断。onmousedown事件第一步先要判断按的元素是否为可拖拽的句柄,然后再给document添加onmousemove、onmouseup事件。onmousemove里是主要的逻辑处理的事件,先根据event事件获取鼠标位置,然后设置拖拽模块的top和left值,最后使用window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty()来取消拖拽过程中选择文本。

二、计算坐标位置

在拖拽模块过程还需要判断元素的坐标位置,因为拖动的模块只能放在指定的几个区域内,所以就需要动态判断是否在指定区域内容,在区域内的那个模块前,这些都需要根据元素的坐标来判断。先判断是否区域,区域栏为树直排列的容器,因此,只需要判断当前鼠标x坐标>=区域x坐标,并且鼠标x坐标<=区域x坐标+区域宽度即可。同理,确定区域后,判断模块是根据当前鼠标y坐标>=模块y坐标,并且鼠标y坐标<=模块y坐标+模块高度,相当于判断鼠标是否在某个元素上,依此可以定位当前拖放元素的区域模块位置,并insertBefore插入一个空元素顶位,再在onmouseup事件里把顶位的空元素替换为当前拖拽的元素,清空拖动时设置的position等样式。在拖放过程中,冒似在IE里计算还有点问题,有时候发现计算出来的位置不正确。另外还发现一个bug,在拖拽时如果用滑轮滚动页面,拖动的元素会滑落在鼠标位置,导致隔空拖动,因为拉滚动条的时候并不会触发onmousemove事件,去看了下iGoogle的首页,发现也存在这个问题,我想可能需要添加window.onscoll事件监视才能解决了。

三、保存拖拽后位置

拖拽完成onmouseup事件处理相对简单,因为在onmousemove事件中已确认拖动模块的位置了即上面所说的顶位的空元素,此时只需要replaceChild为拖拽的模块,但还有一个重要的步骤,那就是前台与后台交互,把当前客户端拖拽后的模块位置状态保存起来,或是写入进数据库。这可能就是一个比较复杂的过程了,因为这干系到数据库表存放结构等,我这里的模块表存放字段有模块ID、区域ID、排序号等,所以客户端保存的时候至少要能获取这些信息,这里我在与后台动态输出模块时就有一个约定,那就是每个模块和区域的DIV里的id或class都包含这些信息,以便客户端能用js方便取到,至于排序则是遍历模块时可自动生成一个从1开始的序号,之后在是把这些信息传递到服务端保存,发送Ajax请求这里就不罗嗦了,使用iframe也行。不过我这里两种方法都没有用,因为用户登陆进后台也可以设置所有模块的栏位和排序,前台我暂只是用Cookie来临时保存所有模块的栏位和排序,不过以后要能在前台拖拽保存所有模块的栏位和排序也很简单了,加个动态页面响应Ajax请求保存所有模块的栏位和排序写入数据库即可。

重要修复:使用添加mousewheel滚动鼠标滑轮事件修正隔空拖拽问题,但还需正确的计算出每次鼠标滑轮的距离。(2010-4-3 17:25)

事例:Drag.html

源码:(Drag.js下载)

热点排行