
先说一下整体结构吧~
页面跳转用了pushstate 加 ajax,评论用了畅言的api 加上 react,前端集成用了grunt,博客是用markdown写的,为了一些特殊需求,自己试着改了一些grunt,这些地方刚好也算是对一些新技术的练习。整体还是jquery。不过这次比我的主页有一点改进,图片我都进行压缩了···
写这些算是对自己这段时间的一次总结好了。
先讲一下菜单样式,跳转机制。
首页的菜单样式如下(less):
- .index-nav{
- width:120px;height:120px;line-height:120px;color:#fff;font-size:26px;margin-top:20px;position:relative;cursor:pointer;
- &:before{content:"";width:90%;height:90%;display:block;position:absolute;margin:5%;border-radius:50%;border:0;border:4px solid transparent;border-top:4px solid #fff;transform:rotate(-45deg);
- transition:.5s
- }
- &:hover{
- color:#fff;
- &:before{transform:rotate(135deg);}
- }
- }
复制代码
然后我们需要进行跳转,这里把参数都写在元素里:
- <div class="index-nav index-nav-02" click-target="change-btn" data-level="1" data-type="bottom" data-model="css" data-url="css">css</div>
- <div class="index-nav index-nav-03" click-target="change-btn" data-level="1" data-type="top" data-model="essay" data-url="essay">随笔</div>
- <div class="index-nav index-nav-04" click-target="change-btn" data-level="1" data-type="bottom" data-model="phrase" data-url="phrase">短语</div>
复制代码
然后绑定点击事件:
- $(document)
- .on('click','[click-target="change-btn"]',function () {
- var data = $.extend({},{level:'1'},$(this).data());
- setPageState(data);
- })
复制代码
这里把点击事件用on定义在document上。避免一些不必要的麻烦。它把参数取到,然后在setPageState方法里组成页面的url以及跳转方式的参数,并调取相应的方法。
然后页面跳转,用到了pushstate。它可以实现无刷新的跳转,整体的思路就是他负责改路径,然后具体的改页面的方式 交给你来处理。
我的实现思路就是,先用grunt的模板功能(也许以后会详细写)让所有的页面都是同一个“壳子”,只有里面的具体内容不一样,这个壳子有head信息,有css样式,js文件,以及都要用到的跳转时出现的大部分蒙版。
然后当用pushstate改变了路径时,就用jquery的ajaxload,只更改内容不一样的部分,这样无刷新行程的页面就和你刷新之后形成的页面是一样的了。
当然,由于我的这个页面有些复(ling)杂(luan),所以定义了三个容纳内容的地方。
具体代码就是:
- /* 设置页面 */
- var setPageState = function (data,flag) {
- if(!(data && data.level && data.model)) data = DEFAULT_STATE;
- var url = $.setUrlWidthVars(data,PATH);
-
- if(flag) {history.replaceState(data,'',url); return;}
- history.pushState(data,'',url);
- buildPage(data);
- }
复制代码
- /* 来一发略复杂的建立页面的大事件!!!! */
- var buildPage = function (data) {
- var l_state = $body.data(), n_state = data;
- if(!(l_state && l_state.level && l_state.model)) l_state = DEFAULT_STATE;
- if(!(n_state && n_state.level && n_state.model)) n_state = DEFAULT_STATE;
- var l_level = l_state.level,n_level = n_state.level;
- //show animate
- if(l_level == n_level && l_state.model == n_state.model) return;
- var flag = 'hide';
- l_state['type'] = n_state['type'] = 'bottom';
- if(l_level > n_level) {
- flag = 'down';
- l_state['type'] = 'page';
- }else if(l_level < n_level) {
- flag = 'up';
- n_state['type'] = 'page';
- }
- var le = $.Event(flag+'.' + l_state.model ,{l_state: l_state, n_state : n_state});
- console.debug(flag+'.' + l_state.model );
- $body.trigger(le);
- }
复制代码
这里把所有触发的事件都绑定在了body身上,有就调用,没有就拉倒,用来处理不同的行为。
然后我们要监听前进和后退按钮:
- /* 绑定popstate 事件 */
- window.addEventListener("popstate", function(e) {
- if(!e.state) return;
- buildPage(e.state);
- });
复制代码
注意一下,较早版本的chrome以及safari会在刷新的时候也去调用popstate事件,所以我们用 里面的state来隔离一下。
然后就是跳转的动效了,我把页面分成了两级,菜单导航的页面都是一级,博客页面都是二级,这里只说一级页面之间的跳转样式。
每一个模块都有一个model,一级页面跳转需要两步,第一步是隐藏当前的model,第二部是展现要展现的model。
所以当一级页面之间跳转的时候,buildPage方法就会调hide.XXX 方法,hide.XXX根据模块的不同,做一些不同的更改,在同一调用hideLevel_1方法。完成hide操作,同时调用show.XXX事件,完成show的操作。
每一个模块还有一个type,因为这些菜单有两种展现形式,一种是在蒙版上弹出(如随笔模块),另一种是在蒙版全部盖住屏幕时候进行更换(如css模块)。
这时候会把内容存放在两个不同的内容区域里,我把它们取名为 top 和bottom。
css模块代码示例:
- .on('show.css',function (e) {
- var delay = 0;
- showLevel_1(e.l_state,e.n_state,delay);
- })
- .on('hide.css',function (e) {
- var delay = 0;
- hideLevel_1(e.l_state,e.n_state,delay);
- })
复制代码
而随笔模块,需要在事件中做一些改变:
- // essay
- .on('show.essay',function (e) {
- var delay = 0, n_state = e.n_state;
- n_state['type'] = 'top';
- showLevel_1(e.l_state,n_state,delay);
- })
- .on('hide.essay',function (e) {
- var delay = 500, l_state = e.l_state;
- l_state['type'] = 'top';
- hideLevel_1(l_state,e.n_state,delay);
- })
复制代码
然后是动画效果中的蒙版,css代码如下:
- /* 前方蒙版 */
- @fullScreen-delay:95ms;
- .full-screen{position:fixed;top:0;left:0;right:0;bottom:0;z-index:2; display:none;
- >li{width:100%;height:10%;transition:400ms; background-repeat:no-repeat;background-size:100% 1000%;
- transform:rotateX(90deg);
- &:nth-child(1){transition-delay:@fullScreen-delay*1;background-position:0 0;}
- &:nth-child(2){transition-delay:@fullScreen-delay*2;background-position:0 11.1%}
- &:nth-child(3){transition-delay:@fullScreen-delay*3;background-position:0 22.2%;}
- &:nth-child(4){transition-delay:@fullScreen-delay*4;background-position:0 33.3%;}
- &:nth-child(5){transition-delay:@fullScreen-delay*5;background-position:0 44.4%;}
- &:nth-child(6){transition-delay:@fullScreen-delay*6;background-position:0 55.5%;}
- &:nth-child(7){transition-delay:@fullScreen-delay*7;background-position:0 66.6%;}
- &:nth-child(8){transition-delay:@fullScreen-delay*8;background-position:0 77.7%;}
- &:nth-child(9){transition-delay:@fullScreen-delay*9;background-position:0 88.8%;}
- &:nth-child(10){transition-delay:@fullScreen-delay*10;background-position:0 99.9%;}
- }
- &.current >li{transform:none;}
- }
- .index .full-screen >li{background-color:@color0;background-image:url(../images/index-background.jpg)}
复制代码
通过background-position 把背景图片分成十块,然后用transform做翻转,就可以行程效果了。
注意一下分成十块你要用100除以9··· 原谅我数学不好,还是不明白为什么···
大概菜单的跳转就这么多,主要就是对pushstate的应用,以及jquery中on和trigger的运用.
via:http://www.gbtags.com/gb/share/4885.htm