代码改变世界

[原创] 从列表页面“切换”到详细页面---两个神奇的div

2012-01-03 22:33  stevey  阅读(3048)  评论(34编辑  收藏  举报

需求场景:在我们做web 前段开发的时候,可能会遇到这样的场景。在一个列表(list)页面,如下图:

当我们前进到第10页时候,选中一条数据,点击编辑,会跳转到如下的详细(detail)页面,如图:

提出问题:我们是如何跳转到这个详细页面的呢?

1.最直接的方法,window.location=details.aspx.

现在问题来了,如果是直接重定向到详细页面,那么在返回列表的时候,会不会遇到什么问题。

在返回的时候,假设返回执行的代码:window.location=list.aspx。这样就会返回到列表,没错,可是回到了列表的第一页啊。

上面假设的这种跳转,会出现“状态”丢失的情况。

或许有同学说了,直接将参数传递到详细页面不就ok了,然后在返回的时候把参数在回传到列表页面。这样从理论上可以解决此问题,假如,列表还带有很多查询条件呢,还有分页参数呢?传递参数是不是最佳做法呢?

”传递参数方案“,有以下缺点:

  1.要把列表(list)也的 查询条件,分页数据,等传递到详细页面(detail)。传递过程比较复杂。

  2.当返回列表页面时候,会将这些参数回传,那么列表页面会“刷新”。用户体验不够良好,刷新意味着重新获取数据。

  3.当列表页面上,有很多状态信息时候,返回时候如何保证呢(比如:选中了一行,当返回时候还要把哪行数据选中)?

    。。。。。

 

针对这样的场景有没有更好更简单的解决方案呢?或许有同学已经想出来了,我在演示这个效果给我们经理看的时候,他一下就猜出来如何实现的了

  思路:“在list页面放置两个div,一个div存放当前列表页面的内容,另一个div存放详细页面,当前往详细页面时候,把第一个div隐藏,第二个div显示,当返回时候,第二个div隐藏,第一个div显示。”-------------------这个想法,不是在洗澡的时候出现的,而是在睡觉前灵光一现,如有雷同,纯是巧合,哈哈

  这样就完完全全保存了列表页面的状态,当点击详细页面时候,直接显示第二个div,这个div中可以是ajax的数据,也可以是iframe页面。返回时,直接显示第一个div,这样就“完完全全”回到了前往详细页面之前的那个列表页面了。

  我们可以把创建这两个div的代码及切换效果封装一下。根据思路,我们需要做的事情。

  1.动态创建这个两个div。

  2.当切换到详细页面时候,需要 一个函数,实现切换。

  3.当点击返回时候,需要一个函数实现,返回切换。

实现代码:

   第二个div里面实现为iframe页面,该代码使用jQuery,有一个Form的命名空间。

1 //depends:jquery.js
2 ; (function($) {
3 $.extend($, {
4 UI: {
5 Dialog: {},
6 Form: {}
7 }
8 });
9 })(jQuery);

 

View Code
 1 ; (function($) {
2 //start
3 var settings = {
4 MianDivID: "_mainFormContainer",
5 PopDivID: "_popFormContainer",
6 PopIframeID: "_popFormIframe",
7 CloseFormBtnID: "_sysCloseFormBtn"
8 };
9 var _initCallBack = function() { };
10 var _showPopFormCallBack = function() { };
11 var _showMianFormCallBack = function() { };
12
13 var InitPageContainer = function() {
14
15 _initCallBack = arguments[0] || function() { };
16 _showMianFormCallBack = arguments[1] || function() { };
17 _showPopFormCallBack = arguments[2] || function() { };
18
19 if ($.browser.msie && $.browser.version == "6.0") {//如果是ie6
20 setTimeout(function() {
21 var form = $("form").eq(0);
22
23 form.wrapInner("<div id=\"" + settings.MianDivID + "\"></div>");
24
25 var popFormHtml = "<div id=\"" + settings.PopDivID + "\" style=\" display:none;\">";
26 popFormHtml += "<iframe id=\"" + settings.PopIframeID + "\" width=\"100%\" height=\"100%\" frameborder=\"0\" src=''></iframe></div>";
27 popFormHtml += "<input type=\"button\" id=\"" + settings.CloseFormBtnID + "\" style=\" display:none;\" />";
28
29 form.append(popFormHtml);
30 $("#" + settings.CloseFormBtnID).click(function() {
31 ShowMainForm();
32 });
33 _initCallBack(); //回调初始化
34 }, 0);
35
36 }
37 else {
38 var form = $("form").eq(0);
39
40 form.wrapInner("<div id=\"" + settings.MianDivID + "\"></div>");
41
42 var popFormHtml = "<div id=\"" + settings.PopDivID + "\" style=\" display:none;\">";
43 popFormHtml += "<iframe id=\"" + settings.PopIframeID + "\" width=\"100%\" height=\"100%\" frameborder=\"0\" src=''></iframe></div>";
44 popFormHtml += "<input type=\"button\" id=\"" + settings.CloseFormBtnID + "\" style=\" display:none;\" />";
45
46 form.append(popFormHtml);
47 $("#" + settings.CloseFormBtnID).click(function() {
48 ShowMainForm();
49 });
50 _initCallBack(); //回调初始化
51 }
52 }
53 var ShowMainForm = function() {
54 $("#" + settings.MianDivID).show();
55 $("#" + settings.PopDivID).hide();
56 $("#" + settings.PopIframeID).attr({ "src": "#" });
57 _showMianFormCallBack();
58 }
59 var ShowPopForm = function(navigateUrl) {
60 $("#" + settings.MianDivID).hide();
61 $("#" + settings.PopDivID).show();
62 $("#" + settings.PopIframeID).attr({ "src": navigateUrl });
63 _showPopFormCallBack();
64 }
65 var ClosePopForm = function(isCallback) {//关闭具体功能页面
66 var isRefresh = true; //是否回调父页面函数
67 if (isCallback != null) { isRefresh = isCallback; }
68
69 var btn = parent.document.getElementById(settings.CloseFormBtnID);
70 if (btn != null) {
71 btn.click();
72 }
73 else {
74 try {
75 btn = window.opener.document.getElementById(settings.CloseFormBtnID);
76 if (btn != null) {
77 if (isRefresh) {
78 btn.click(); //点击
79 }
80
81 }
82 } catch (e) { }
83 window.opener = null; window.open("about:blank", "_self"); window.close(); //关闭页面
84 }
85 }
86
87 /* -----[ Exports ]----- */
88
89 $.UI.Form.Settings = settings;
90 $.UI.Form.Init = InitPageContainer;
91 $.UI.Form.Open = ShowPopForm;
92 $.UI.Form.Close = ClosePopForm;
93
94 //end
95 })(jQuery);

 

使用方法:
1、 在list页面,dom加载完毕后,执行注册。

1 //初始化【主操作页面】切换到【具体操作页面】环境
2 $.UI.Form.Init(function() {//初始化回调
3
4 }, function() {//当回到主操作页面时,要执行的回调
5 $("#grid1").trigger("reloadGrid");
6 });

2、切换到详细页面代码:

$.UI.Form.Open('detail.aspx?id=101&name=a')

3、返回代码:

$.UI.Form.Close(bool);

以上实现已经用在项目中,但还没来得及在认真整理封装下,供大家参考

上面的代码并没有满足所有情况的需要,请同学们根据需要自行完善。需要完善的地方如下:

  1.第二个div是ajax得到的数据。

  2.当在返回时候,调用Close函数时,传入bool类型或者参数,实现控制返回的回调函数,执行,控制是否需要刷新列表等其他操作。
  3.。。。。。。

两个div的显示隐藏,可以解决上面“参数传递方法”的具有的缺陷问题,并且第二个div的里面如果是iframe的话,嵌套的页面还可以继续使用该切换,这样返回回去时候,状态是没有任何丢失的,如果有同学有更好的解决办法,欢迎提出交流。

总结:
  我称这个跳转叫做“切换”,类似apple的应用程序,从一个界面,切换到第二个界面,并且有滑动效果(可以自己实现),可以一级一级的返回,思路就是两个div的显示隐藏。

 

  第一次写blog,可能表达方式,描述,排版,等有些欠缺,还请各位同学包涵,我们重在交流思路,哈哈。希望阅读此文后,能对你有所帮助!

  有什么疑问请提出来,我们共同讨论,共同进步,谢谢大家!