快生活 - 生活常识大全

教程网站后台多页签功能增强版


  很多网站后台或者B/S结构的应用系统,经常会有这样的功能:左侧是导航菜单,点击菜单后会在右侧主区域以页签(也可称为选项卡)的形式打开页面,然后再点击第二个个菜单,右侧主区域会打开第二个页签来显示页面。如果对这个功能不太熟悉的话,可以去看一下Web版的邮箱系统(比如什么浪什么易之类的)。那今天分享的案例就是教大家使用中继器与内联框架实现网站后台的多页签功能。
  1、原型解析
  这个功能看起来简单,但如果深入探究就会发现很多逻辑问题。
  问题1:点击菜单,在主区域显示该菜单对应的页签和页面。
  扩展1:如果该菜单对应的页面未打开,则在新页签中打开页面;
  扩展2:如果该菜单对应的页面已打开但未显示,则在原页签中显示页面;
  扩展3:如果该菜单对应的页面已打开且已显示,则不进行任何操作。
  问题2:页签和页面需要对应同步显示。
  问题3:当打开多个页签之后,点击页签可以切换对应的页面显示。
  问题4:当前显示的页面对应的页签需要突出显示。
  问题5:点击页签上的关闭图标可以同步关闭页签及对应的页面。
  扩展1:如果关闭的是当前显示的页面,关闭后显示上一个打开的页面;
  扩展2:如果关闭的不是当前显示的页面,关闭后仍然显示当前页面。
  2. 设计思路
  这个功能整体包含三个部分:菜单部分、页签部分、显示页面的部分,我们来思考一下这三个部分分别用什么元件来实现。
  针对菜单部分:可选的元件很多,在此不一一列举,只要是能点击的元件基本就可以,但使用不同元件的结果就是过程复杂程度不同以及灵活程度不同。但考虑到原型的通用性,不同情况下菜单项是不同的,于是考虑使用更为灵活的中继器元件来做菜单。
  针对页签部分:因为这一部分会涉及到页签的动态增减,所以毫不犹豫选择中继器。
  针对显示页面的部分:由于要跟随不同的菜单或页签来显示不同的页面,所以基本也是动态显示,可以考虑的元件有三种方案,一是内联框架,二是动态面板+内联框架,三是中继器+内联框架,因为要显示页面,所以内联框架是必不可少的。那这三种方案如何选择呢?通过简单对比,可以发现第三种方案比第一种方案适用范围更广,比第二种方案配置更加简单,所以采用第三种方案。
  那么三部分要使用的元件都确定之后,接下来就是在此思路的基础上去实践(踩坑)了。
  本案例中三个部分,全部使用中继器来实现,好处则是配置简单,灵活度高,可复用性强。如果你尝试了其他元件,你就会理解使用中继器真的是一劳永逸。
  3. 制作过程
  3.1 准备三个中继器
  在画布上拖入三个中继器,分别命名为"菜单"、"页签"、"页面",并参照下面步骤进行设置。
  (1)设置"菜单"中继器
  设置中继器的列为"id"(其值需要具有唯一性),"menu"(存储菜单名称)和"url"(存储菜单指向的页面链接)并添加一些自定义数据,中继器中自带的"矩形"元件样式请自行设置。修改中继器的"每项加载时"用例。
  (2)设置"页签"中继器
  设置中继器的列为"id"和"menu",并清空自带的数据,中继器中自带的"矩形"元件样式请自行设置,修改中继器的"每项加载时"用例。
  (3)设置"页面"中继器
  设置中继器的列为"id","url"和"sort"(存储排序序号),清空自带数据,保留一个空白行(或在url中定义一个初始页面),删除中继器中的矩形,并拖入一个内联框架,修改中继器的"每项加载时"用例,修改中继器的分页样式(多页显示,每页项目数1)。
  3.2 实现点击菜单打开页签及页面
  回到"菜单"中继器中,在"矩形"元件上设置"鼠标单击时"用例,分别向中继器"页签"和"页面"中插入一行数据。"页签"中继器中插入的是当前菜单的"id"和"menu",以便新增的页签可以显示菜单的名称,"页面"中继器中插入的是当前菜单的"id"和"url",以便新增的页面可以在其内联框架中显示菜单对应的页面。
  这时候我们可以预览一下原型,当你点击菜单时,你会发现:页签不断向后增加,而页面并没有显示(或者只显示了第一个菜单对应的页签,之后的就不再显示),没关系,我们现在总结一下原型存在的问题,然后在接下来的步骤中逐一解决。
  其实这里会出现很多问题,有简单有复杂,这里我根据问题的优先级先拿出三个来解决,因为解决了这三个问题,我们的原型在要求比较低的情况下可以到此为止了,已经能够满足基本的演示。那这三个问题就是:
  问题①:页面不能正常显示
  问题②:我希望点击已打开的页签时,实现页签及页面的切换
  问题③:我希望当前打开的页签可以突出显示
  3.3 解决页面不能正常显示的问题
  熟悉中继器的朋友这时候应该马上就能知道页面不能正常显示的原因,因为我们在前面设置中继器的时候,配置了中继器的分页属性,即每页显示一个项目,而我们在点击菜单的时候,每点击一次就会像中继器中增加一个项目,但是增加的项目默认是排在后面的,也就是排在了第2页,第3页,第N页。所以我们只能看到第一个菜单的页面,之后点击的菜单的页面就看不到。
  明白了问题的原因就容易解决了,我们只需要将后点击的菜单插入的项目排列在最前面就可以了,那这里就用到了中继器的排序功能,跟着下面的步骤继续操作。
  首先添加一个全局变量"sort"(或将默认的全局变量名修改为"sort"),然后修改菜单的"鼠标单击时"事件。在点击菜单的时候,给sort值+1,给"页面"中继器增行的时候,设置sort值等于新的全局变量sort值。这样做就可以使得每次打开的页面的sort值都比上一个大1,然后利用中继器的排序功能就可以将最后打开的页面排在最前面。
  然后我们再给中中继器"页面"添加排序功能,排序动作可以在中继器"载入时"来执行。
  这时候再来预览,我们可以发现无论如何点击菜单,页面都可以正常显示了,上面的问题①解决。接下来再解决问题②。
  3.4 点击页签切换页面
  这个问题比较容易解决,根据上一步中页面的显示逻辑,点击页签的时候,只需要更新一下"页面"中继器中的sort值即可(在最新的全局变量sort值的基础上+1)。
  3.5 最新打开的页签突出显示
  突出显示的样式我们可以设置页签中形状的"选中"样式来实现,如果是当前点击的菜单对应的页签,就将其设置为选中,以激活其选中样式。那么问题来了,什么时候设置页签中形状的选中呢?又如何知道该设置那个页签的?
  这个问题可简单可复杂,简单的情况就是,我们只考虑点击菜单或者点击页签切换显示的时候,点击哪个菜单或页签,对应的页签就选中,只要通过菜单和页签的id进行判断就可以。但是,还有一种复杂的情况要考虑,那就是,如果关闭了一个选中状态的页签该怎么办呢?剩余的页签该让谁处于选中状态呢?显然前面的解决方案是没有办法解决这一问题的,我们还需要从长计议。
  寻找这个问题的解决方案时,让我走了不少弯路,尝试了N种方式,有的根本行不通,有的表面行得通但时不时的会出现失灵的情况,不过幸运的是,最终还是找到了一种完美的解决方案。方案如下:
  首先,点击菜单或者页签时,以此记录其id形成id串,比如[id1][id2][id3][id4]这样,但根据后面的实践经验得知,记录的顺序需要按照从后往前的顺序,即最新点击的菜单或页签的id放在最前面。
  然后,在"页签"中继器的每项加载时,判断当前页签的id是否等于id串最前面的那个id,如果是就选中,如果不是就不做任何操作。如果最前面的id被删除了(关闭页签的时候),那么第2个id(也就是上个页签)就变成了最前的,从而也解决了关闭页签时,可以使上一个页签突出显示的问题。
  具体到原型中,需要创建两个全局变量"id"和"ids",id用来记录当前id,ids用来记录id串,然后在菜单和页签的"鼠标单击时"事件中增加更新ids的动作。最后在"页签"中继器的每项加载时执行判断并设置选中。
  菜单的"鼠标单击时"用例:
  页签的"鼠标单击时"用例:
  页签的"每项加载时"用例:if "[[ids.indexOf(Item.id)]]"=="0″的意思就是当前id在ids中的位置是0(0代表第一位),设置选中效果。
  此时还需要添加一个Case2,即使上面条件不成立,我们依然需要在页签上显示菜单名称。
  这时候我们来预览一下页面,是不是页签的选中效果已经出来了,但是竟然还有一个问题,就是切换页签的时候,页签的选中效果并没有在页签之间切换,这是为什么呢?这是因为"页签"中继器没有刷新(也就是没有重新加载),我们需要在每次点击页签时,让其重新加载一下,实现方式就是给"页签"中继器增加一个更新操作(不需要跟新任何数据,只添加这样一个动作就可以)。
  这次再预览,切换页签的时候,选中效果也随之切换了。到目前为止,此原型已经基本可以拿去演示了,但是如果想要精益求精,不想让原型存在一些很明显的BUG,那么我们还要继续完善,进一步解决原型存在的问题:
  问题④:重复点击菜单会打开重复的页签,我们只想打开一个页签
  问题⑤:我想实现关闭页签的功能
  3.6 解决重复打开页签的问题
  要解决此问题,我们只需要在点击菜单的时候加上判断条件即可,如果该菜单未打开(或打开后又关闭),则执行增行操作;如果该菜单已打开,则只执行更新操作(更新ids和页面sort)。那么通过什么来判断菜单当前是不是处于打开的状态呢?答案是通过中继器的标记功能,打开时标记菜单,关闭时取消标记。
  修改"菜单"中继器中矩形上的"鼠标单击时"用例Case1,增加判断条件及标记动作。
  添加Case2,当菜单已被标记的时候,执行更新操作。
  通过以上步骤,就可以避免同一个菜单打开多个重复的页签,预览原型看下效果吧。
  3.7 关闭页签
  由于前面打下了良好的基础,关闭页签功能的实现就比较简单了,只需要删除ids中对应的id(利用replace函数,将ids中的id替换为空以实现删除的效果),删除页签和页面(中继器的删除行功能),然后再取消菜单的标记(中继器的取消标记功能)就可以了。(如果没有关闭按钮,现在"页签"中继器中增加一个关闭图标)
  设置关闭按钮的"鼠标单击时"用例。
  到这里,原型已经基本完成了,然后去预览一下,随意的去点击菜单,切换或关闭页签,你会发现效果非常理想。当然仍然还有一些可以优化的地方,比如控制最多打开的页签数,比如重复点击当前显示的页签不再刷新页面等等,那么这些问题留给大家去自行研究吧,当然有问题可以与我交流。
  4. 经验总结
  其实,画原型并没有统一的标准,是要低保真还是高保证。就好比做项目,同样的需求,一个月有一个月的做法,一个星期有一个星期的做法。而画原型也是,同样的功能,根据不同的用途可以有不同的画法,可简可繁。另外对于一些复杂的原型,在考验你工具熟练度的同时,也是在考验你的逻辑思维能力。Axure RP不仅仅是原型工具,画原型也不仅仅是"画"原型。
网站目录投稿:向山