题外话:刚开始学前端的时候,有一天看到携程官网.就但愿有一天能模拟搭出来.
本身拖拖拉拉的一直没整, 可是可是麻麻我终于完成了!!
(曾经亲爱的同事把传送门删掉了不感谢他了 fk)
感谢叶师兄拯救了我携程携程 源码仿携程源码javascript
小小讲一下本身拿到携程官网的时候是怎么拆开的(若是写的不对请麻烦各位指出指导)
刚刚学前端的时候 看到携程网就乱拳敲打.一点点html css强写,
后面工做的缘由用了vue,就推倒旧的从新写了.css
页面结构是分为这几块:(如图)html
哎,没想到好的办法.就搭页面的时候,顺便在携程网上面一点点的copy下来.
(我看隔壁的仿页面贴都是经过接口的.小弟仍是菜了点)
而后经过每一个须要数据的页面去引入这个mock.js...前端
普通的页面样式就不说啦.你们慢慢搭就好.
share一些less的mixin方法.vue
// display vertical集合 #display_type{ .dsp-middle{ display: inline-block; vertical-align: middle; } .dsp-top{ display: inline-block; vertical-align: top; } } // 三角形(向下) .arrow_down(@size, @color: black){ //@size大小 @color颜色 margin-left: 5px; &:after{ content: ''; display: inline-block; border-top: @size solid @color; border-left: @size solid transparent; border-right: @size solid transparent; border-bottom: @size solid transparent; } }
用的比较多的2个mixin就是上面这2个.一个是display的作布局使用, 一个是人工三角形orz.
若是想要用mixin的时候,须要在css中用@import的方法引入才能用.(用js的方式,破了很久破不了放弃)java
由于个人样式是经过less写的.
那就看着携程官网.一点点测试.一点点完善咯.没啥好办法.
部分代码以下.node
@media screen and (max-width: 1200px){ margin-right: 20px; &:last-child{ display: none; } }
这个电梯是存在于专题区里面的,因此我给每一个专题的div添加了一个不用的类名,用来获取当前div的滚动高度.
而后在钩子函数mounted()里面,去获取各个专题的高度git
const s = document.getElementsByClassName('scroll-hook'); for(let dom of s){ let scoll_h = dom.offsetTop + dom.offsetParent.offsetTop; this.scroll_data.push(scoll_h); }
电梯的精髓就是在:github
那么就对应的写bie.vue-cli
1.电梯的html渲染(ps. lift.index是每个电梯的类名, lift_flag是区域的标识),而后在mounted()里给window注册一个scroll的监听事件,而后去获取当前的滚动高度,而后进行判断
<ul class="lift-wrapper" :style="`top:${lift_top}px;`"> <li class="lift-item" :class="[lift.index, {'lift-active': (lift_index === lift_flag)}]" v-for="(lift,lift_index) in d" @click="lift_click(lift_index)"> <span class="skip">{{lift.name}}</span> </li> </ul>
2.点击滚动,写了一个原生的笨方法,(document.dEl那有一个兼容问题)
//页面滚动方法 function page_scroll_to(cur, tar){ /* params: cur 当前高度 tar 目标高度 */ var during = 10; //持续时间(ms) var times = 20; //持续次数 var i = 1; //持续标识 var s_flag; if(cur < tar){ var s = (tar - cur) / times; //滚动距离 s_flag = setInterval(() => { //解决兼容性问题(本来使用documentElement便可) document.documentElement.scrollTop = cur + s * i; document.body.scrollTop = cur + s * i; i++; if(i>times){ clearInterval(s_flag); } }, during) } else{ var s = (cur - tar) / times; s_flag = setInterval(() => { //解决兼容性问题 document.documentElement.scrollTop = cur - s * i; document.body.scrollTop = cur - s * i; i++; if(i>times){ clearInterval(s_flag); } }, during) } }
3.样式我是直接copy携程的. 滑动高度呢就根据滚动高度去计算, 而后用js给电梯的div写一个内联样式,动态的去改变
由于给window注册了一个scroll事件,当你一滚动,会疯狂触发scroll,可能在线上的会致使浏览器有压力(猜的)
因此本身写了一个throttle方法去优化这一块,
而后在vue的原型对象中注册了一下,能够在后续直接this.throttle只用
function throttle(fn, delay, context) { /* throttle函数(每delay时间,触发一次fn函数) param: fn 执行函数 delay 持续时间(ms) context 做用域 */ var last; //定时器 var timer; return function(){ //获取当前的毫秒数 var now = +new Date(); //判断时间 if(last && now < last + delay){ clearTimeout(timer); timer = setTimeout(function() { last = now; fn.apply(context); }, delay) } else{ last = now; fn.apply(context); } } } Vue.prototype.throttle = throttle;
页面大了一进入就触发所有的请求,确定不那么棒,因此此处引入了lazyload.
携程的lazyload除了图片.还有每一个专题区(忽略爱心 - -).
ps.最开始引用了vue-lazyload这个模块,而后里面有一个lazyComponent配置项,能够用来设置一整块的,可是这个有一个不足的地方,就是当你页面在比较下面的时候去刷新, lazyComponent只会update当前可视区域的部分,可视区域上面的区域就无论你........
pss.因此我本身经过上面的电梯,本身写了一个,而后将flag标识经过组件之间传入,而后组件内部经过watch去监控.而后动态从初始化状态更新为内容区.
其实就是一个普通的页面搭建,你们若是有空其实一点点就能搭出来的,
不知道强行分享的东西有没有更好的方法呢,若是有麻烦各位指导一下小弟.
以上完毕,感谢你们感谢你们.(若是侵权了,立刻下架,仅供交流学习)
最后最后,携程在手,说走就走.