[关闭]
@lizlalala 2017-01-05T04:01:17.000000Z 字数 5970 阅读 1185

fe日常玩耍

css js underscore 无限滚动 throtte


toggle button

toggle button via css@luchenCodePen

小记:
有几个重要点呐:
- input 的id与 label的for属性对应,使得label可以检测input的check事件,否则点label是不能触发check的。
- css3中:checked 属性," + "兄弟选择符。使得可以对选中状态下的label进行css编写
- todo 用transform,尽量不用left这些。以达到平滑效果 【done】
确实过渡会平滑很多。


scrollbar

js实现滚动条@luchenCodePen

recipe:

这边是以一个小的div为例。

如果想全局滚动条,类似于阮一峰es6教程上的那种效果。

则应该相应的变为

  1. $(window).scrollTop()
  2. $(window).height()
  3. $(document).height()

补充知识:

补充

  1. if ( jQuery.isWindow( elem ) ) {
  2. return elem.document.documentElement[ "client" + name ];
  3. }
  4. // Get document width or height
  5. if ( elem.nodeType === 9 ) {
  6. doc = elem.documentElement;
  7. // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
  8. // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
  9. return Math.max(
  10. elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  11. elem.body[ "offset" + name ], doc[ "offset" + name ],
  12. doc[ "client" + name ]
  13. );
  14. }

模拟操作

很久以前我萌还在用jquery的时候,很喜欢用的一个函数是trigger,但是离开了jquery,还有什么方法可以实现同样的问题,楼主一直很困惑...一直到看了mdn的相关api,具体demo请戳自定义事件及触发
划重点就是:

  1. var event = new Event()
  2. target.addEventListener("自定义名称")
  3. target.dispatchEvent(event);
trigger event@luchenCodePen

references:
1. 创建和触发 events
2. mouseevent


css做tab切换

todo


slider

楼主在开发这部分组件,用的是原生的html5的input中的type=range,实现了这么几个功能:

recipe:

html5 input(type:range)
选择器:


无限滚动

楼主最近在用vue开发cnode的移动端,首页部分有滚动列表,因为我们之前提到过debounce延缓input框发送ajax联想请求。那么这边我们就需要用throtte去实现无限滚动。(无限滚动的原理就是在滚动事件+分页请求+节流)
具体为什么不用debounce,需要体会的是debounce是在停止项某事件或者超过某个限时时才执行一次。滚动并不需要用户在停止scroll才去加载,而是应该在滚动的过程中定时去请求。所以用throtte。
throtte的实现是最简单的版本:

  1. function throtte(func,wait,options){
  2. let lastTime = Date.now();
  3. return function next(){
  4. const now = Date.now();
  5. const gap = now - lastTime;
  6. if( gap >= wait ){
  7. func.apply(this,arguments);
  8. // if(param===options.terminal) return;
  9. lastTime = now;
  10. }
  11. }
  12. }
  13. //调用
  14. created(){
  15. this.fetchPage(1);
  16. this.infiniteScroll = this.infiniteScroll.bind(this);
  17. window.addEventListener("scroll",this.infiniteScroll());
  18. },
  19. infiniteScroll(){
  20. return throtte(this.fetchWhenScroll.bind(this),1000);
  21. },

在实现过程中,还有这么几个问题:

  1. function check_if_needs_more_content(){
  2. //1
  3. const scrollTop = document.body.scrollTop||document.documentElement.scrollTop;
  4. //2
  5. const doc = document.documentElement;
  6. const name = 'Height';
  7. const docHeight = Math.max(
  8. document.body[ "scroll" + name ], doc[ "scroll" + name ],
  9. document.body[ "offset" + name ], doc[ "offset" + name ],
  10. doc[ "client" + name ]
  11. );
  12. //3
  13. const windowHeight = window.innerHeight || document.documentElement.clientHeight;
  14. let distanceToDocBottom = docHeight-windowHeight-scrollTop;
  15. if(Math.abs(distanceToDocBottom)<300) return true;
  16. return false;
  17. }
  18. //调用
  19. fetchWhenScroll(){
  20. if(check_if_needs_more_content()){
  21. this.fetchPage(this.page);
  22. this.page++;
  23. }
  24. },

这种方法的好处在于,避免方向的判断,上滑的时候 distanceToDocBottom实际上是变大的,那么就不需要进行请求。同时由于距离底部的距离限定好,那么从本次加载数据,到下次加载数据,实际上是把本次获得的数据滚动完以后再进行加载的。但是有一点问题是,貌似滑动到最下面的时候会停止,需要上滑一部分才会响应。而且当滚动很多页的时候,distanceToBottom会大于设定的gap。就不会发送请求。待解决。
除此之外,因为公式是jquery版本的。楼主试了很多兼容的原生版本,但是都不太对...就暗搓搓的去github上面搜了jquery这部分的源码...捂脸。

===2016/11/23 更新
楼主的throtte是有点问题的,看了下underscore的函数说明,有两点:

  1. function throtte(func,wait,options){
  2. let isFirst = true;
  3. let funcId,gap,lastTime,duration = 0;
  4. const finalOptions = Object.assign({},{
  5. leading: true,
  6. trailing: true
  7. },options);
  8. if(!finalOptions.leading && !finalOptions.trailing) {
  9. alert("不可以同时设置leading,trailing为负");
  10. return;
  11. }
  12. return function next(){
  13. const now = Date.now();
  14. const context = this;
  15. if( isFirst || (gap = now -lastTime) >= wait ){
  16. //=====更新 2017.1.5
  17. lastTime = now;
  18. if(isFirst){
  19. isFirst = false;
  20. //leading:false时,不执行,等下一次wait的时间以后
  21. if(finalOptions.leading)
  22. func.apply(context,arguments);
  23. }
  24. }
  25. else{
  26. // lastTime-lastTime+wait间进入的函数,需要取消。结束再执行
  27. clearTimeout(funcId);
  28. //trailing true时才执行。
  29. if(finalOptions.trailing)
  30. funcId = setTimeout(function(){
  31. func.apply(context,arguments); //!!context
  32. lastTime = now;
  33. }, wait-gap);
  34. }
  35. }
  36. }

css3常用

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注