做一个略调皮的个人博客--菜单篇

本文介绍了一种利用HTML5的History API(PushState)结合AJAX技术实现网站平滑无刷新页面跳转的方法。通过自定义菜单样式与交互逻辑,配合前端构建工具Grunt及Markdown格式的博客内容,达到了改善用户体验的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9d58068f-ddb5-42ba-82b9-004da116d320.png

4 天前 上传
下载附件 (295.26 KB)


先说一下整体结构吧~


页面跳转用了pushstate 加 ajax,评论用了畅言的api 加上 react,前端集成用了grunt,博客是用markdown写的,为了一些特殊需求,自己试着改了一些grunt,这些地方刚好也算是对一些新技术的练习。整体还是jquery。不过这次比我的主页有一点改进,图片我都进行压缩了···


写这些算是对自己这段时间的一次总结好了。





先讲一下菜单样式,跳转机制。


首页的菜单样式如下(less):


  1. .index-nav{
  2.         width:120px;height:120px;line-height:120px;color:#fff;font-size:26px;margin-top:20px;position:relative;cursor:pointer;
  3.         &: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);
  4.                 transition:.5s
  5.         }
  6.         &:hover{
  7.                 color:#fff;
  8.                 &:before{transform:rotate(135deg);}
  9.         }
  10. }
复制代码


然后我们需要进行跳转,这里把参数都写在元素里:


  1. <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>
  2. <div class="index-nav index-nav-03" click-target="change-btn" data-level="1" data-type="top" data-model="essay" data-url="essay">随笔</div>
  3. <div class="index-nav index-nav-04" click-target="change-btn" data-level="1" data-type="bottom" data-model="phrase" data-url="phrase">短语</div>
复制代码


然后绑定点击事件:


  1. $(document)
  2.         .on('click','[click-target="change-btn"]',function () {
  3.                 var data = $.extend({},{level:'1'},$(this).data());
  4.                 setPageState(data);
  5.         })
复制代码


这里把点击事件用on定义在document上。避免一些不必要的麻烦。它把参数取到,然后在setPageState方法里组成页面的url以及跳转方式的参数,并调取相应的方法。


然后页面跳转,用到了pushstate。它可以实现无刷新的跳转,整体的思路就是他负责改路径,然后具体的改页面的方式 交给你来处理。



685568d1-96ab-41bb-8c74-ca9c24b4bda2.png 


我的实现思路就是,先用grunt的模板功能(也许以后会详细写)让所有的页面都是同一个“壳子”,只有里面的具体内容不一样,这个壳子有head信息,有css样式,js文件,以及都要用到的跳转时出现的大部分蒙版。


然后当用pushstate改变了路径时,就用jquery的ajaxload,只更改内容不一样的部分,这样无刷新行程的页面就和你刷新之后形成的页面是一样的了。


当然,由于我的这个页面有些复(ling)杂(luan),所以定义了三个容纳内容的地方。



具体代码就是:


  1. /* 设置页面 */ 
  2. var setPageState = function (data,flag) {
  3.         if(!(data && data.level && data.model)) data = DEFAULT_STATE;
  4.         var url = $.setUrlWidthVars(data,PATH);
  5.         
  6.         if(flag) {history.replaceState(data,'',url); return;}
  7.         history.pushState(data,'',url);
  8.         buildPage(data);
  9. }
复制代码
  1. /* 来一发略复杂的建立页面的大事件!!!! */
  2. var buildPage = function (data) {
  3.         var l_state = $body.data(), n_state = data;
  4.         if(!(l_state && l_state.level  && l_state.model)) l_state = DEFAULT_STATE;
  5.         if(!(n_state && n_state.level  && n_state.model)) n_state = DEFAULT_STATE;
  6.         var l_level = l_state.level,n_level = n_state.level;
  7.         //show animate 
  8.         if(l_level == n_level && l_state.model == n_state.model) return;
  9.         var flag = 'hide';
  10.         l_state['type'] = n_state['type'] = 'bottom';
  11.         if(l_level > n_level) { 
  12.                 flag = 'down';
  13.                 l_state['type'] = 'page';
  14.         }else if(l_level < n_level) {
  15.                 flag = 'up';
  16.                 n_state['type'] = 'page';
  17.         }
  18.         var le = $.Event(flag+'.'  + l_state.model ,{l_state: l_state, n_state : n_state});
  19.         console.debug(flag+'.'  + l_state.model );
  20.         $body.trigger(le);
  21. }
复制代码


这里把所有触发的事件都绑定在了body身上,有就调用,没有就拉倒,用来处理不同的行为。


然后我们要监听前进和后退按钮:



  1. /* 绑定popstate 事件 */
  2. window.addEventListener("popstate", function(e) {
  3.         if(!e.state) return; 
  4.         buildPage(e.state);
  5. });
复制代码


注意一下,较早版本的chrome以及safari会在刷新的时候也去调用popstate事件,所以我们用 里面的state来隔离一下。


然后就是跳转的动效了,我把页面分成了两级,菜单导航的页面都是一级,博客页面都是二级,这里只说一级页面之间的跳转样式。


每一个模块都有一个model,一级页面跳转需要两步,第一步是隐藏当前的model,第二部是展现要展现的model。


所以当一级页面之间跳转的时候,buildPage方法就会调hide.XXX 方法,hide.XXX根据模块的不同,做一些不同的更改,在同一调用hideLevel_1方法。完成hide操作,同时调用show.XXX事件,完成show的操作。


每一个模块还有一个type,因为这些菜单有两种展现形式,一种是在蒙版上弹出(如随笔模块),另一种是在蒙版全部盖住屏幕时候进行更换(如css模块)。


这时候会把内容存放在两个不同的内容区域里,我把它们取名为 top 和bottom。


css模块代码示例:



  1. .on('show.css',function (e) {
  2.         var delay = 0;
  3.         showLevel_1(e.l_state,e.n_state,delay);
  4. })
  5. .on('hide.css',function (e) {
  6.         var delay = 0; 
  7.         hideLevel_1(e.l_state,e.n_state,delay);
  8. })
复制代码


00cced55-0c4d-46c5-a0d8-5f1d12ad699d.png 


而随笔模块,需要在事件中做一些改变:


  1. // essay    
  2. .on('show.essay',function (e) {
  3.         var delay = 0, n_state = e.n_state;
  4.         n_state['type'] = 'top';
  5.         showLevel_1(e.l_state,n_state,delay);
  6. })
  7. .on('hide.essay',function (e) {
  8.         var delay = 500, l_state = e.l_state;
  9.         l_state['type'] = 'top';
  10.         hideLevel_1(l_state,e.n_state,delay);
  11. })
复制代码


b5f7be2a-d6a3-4b92-bc26-ddc03077f152.png 


然后是动画效果中的蒙版,css代码如下:


  1. /* 前方蒙版 */
  2. @fullScreen-delay:95ms;
  3. .full-screen{position:fixed;top:0;left:0;right:0;bottom:0;z-index:2; display:none;
  4.         >li{width:100%;height:10%;transition:400ms; background-repeat:no-repeat;background-size:100% 1000%; 
  5.                 transform:rotateX(90deg);
  6.                 &:nth-child(1){transition-delay:@fullScreen-delay*1;background-position:0 0;}
  7.                 &:nth-child(2){transition-delay:@fullScreen-delay*2;background-position:0 11.1%}
  8.                 &:nth-child(3){transition-delay:@fullScreen-delay*3;background-position:0 22.2%;}
  9.                 &:nth-child(4){transition-delay:@fullScreen-delay*4;background-position:0 33.3%;}
  10.                 &:nth-child(5){transition-delay:@fullScreen-delay*5;background-position:0 44.4%;}
  11.                 &:nth-child(6){transition-delay:@fullScreen-delay*6;background-position:0 55.5%;}
  12.                 &:nth-child(7){transition-delay:@fullScreen-delay*7;background-position:0 66.6%;}
  13.                 &:nth-child(8){transition-delay:@fullScreen-delay*8;background-position:0 77.7%;}
  14.                 &:nth-child(9){transition-delay:@fullScreen-delay*9;background-position:0 88.8%;}
  15.                 &:nth-child(10){transition-delay:@fullScreen-delay*10;background-position:0 99.9%;}
  16.         }
  17.         &.current >li{transform:none;}          
  18. }
  19. .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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值