UDN-企业互联网技术人气社区

板块导航

浏览  : 376
回复  : 6

[原生js] 【JavaScript吉光片羽】--- 滑动条

[复制链接]
白青青的头像 楼主
发表于 2017-1-3 15:27:51 | 显示全部楼层 |阅读模式
  灯光的亮度控制需要一个滑动条,先借用lamp源码中Bar:
  1. var Bar = function (opt) {
  2.     var defaults = {
  3.         $id: "", // 进度条dom节点id
  4.         min: 1, // 刻度最小值
  5.         stepCount: 5, // 刻度步数
  6.         step: 1, // 刻度步长
  7.         $alpha: "",//显示亮度的id
  8.         touchEnd: function () { } // 拖动完成回调
  9.     };
  10.     this.option = $.extend(defaults, opt);
  11.     this.barNode = $("#" + this.option.$id);
  12.     this.parentNode = this.barNode.parents(".J_slider_box");
  13.     this.sliderNode = this.barNode.find(".J_slider");
  14.     this.fillNode = this.barNode.find(".J_fill");
  15.     this.valNode = this.barNode.find(".J_value");
  16.     this.val = this.option.min;
  17.     // this.valNode.text(this.val);

  18.     this._init();
  19.     return this;
  20. }
  21. Bar.prototype = {
  22.     /**
  23.      * 根据比例值来重新渲染进度条的位置
  24.      * @param ratio 取值:0~1
  25.      */
  26.     refreshPos: function (ratio) {
  27.         if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
  28.             return;
  29.         }
  30.         // 根据触点位置更新进度条
  31.         var percentage = ratio * 100;
  32.         this.sliderNode.css("left", percentage + "%");
  33.         this.fillNode.css("width", percentage + "%");

  34.         var unit = 1 / this.option.stepCount,
  35.             halfUnit = unit / 2,
  36.             a = Math.floor(ratio / unit),
  37.             b = ratio % unit,
  38.             index = a + (b < halfUnit ? 0 : 1);
  39.         this.val = this.option.min + index * this.option.step;
  40.         if (this.option.$alpha) {
  41.             $("#" + this.option.$alpha).html(this.val);
  42.         } else {
  43.             this.valNode.text(this.val);
  44.         }
  45.     },
  46.     /**
  47.      * 设置指定的进度值
  48.      */
  49.     setVal: function (val) {
  50.         var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
  51.         this.refreshPos(ratio);
  52.     },
  53.     _init: function () {
  54.         var bar = this;
  55.         if (!(bar.barNode.width() > 0)) {
  56.             setTimeout(function () {
  57.                 bar._init();
  58.             }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
  59.             return;
  60.         }
  61.         bar.leftDis = bar.barNode.offset().left;
  62.         bar.sliderWidth = bar.barNode.width();

  63.         bar.barNode.on("touchmove", function (e) {
  64.             e.preventDefault();
  65.             // bar.parentNode.addClass("on");
  66.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  67.             var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
  68.             bar.refreshPos(ratio);
  69.         });

  70.         bar.barNode.on("touchend", function (e) {
  71.             e.preventDefault();
  72.             //bar.parentNode.removeClass("on");
  73.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  74.             var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
  75.             bar.refreshPos(ratio);
  76.             bar.option.touchEnd(bar.val);
  77.         });

  78.         bar.refreshPos(this.val);

  79.     }
  80. };
复制代码

  html:
  1.      <div class="lightsider">
  2.                 <div id="lightsider" class="slider_box J_slider_box">
  3.                     <i class="slider_box_icon icon dark"></i>
  4.                     <div id="lightBar" class="slider_box_bar">
  5.                         <div class="slider_box_slider J_slider" style="left:0%">
  6.                             <p class="slider_box_slider_label J_value"></p>
  7.                             <i class="slider_box_slider_touch"></i>
  8.                         </div>
  9.                         <div class="slider_box_line">
  10.                             <span class="slider_box_line_fill J_fill" style="width:0%"></span>
  11.                         </div>
  12.                     </div>
  13.                     <i class="slider_box_icon icon light"></i>
  14.                 </div>
  15.             </div>  
复制代码

  css:
  1. .slider_box {
  2.   display: -webkit-box;
  3.   display: -webkit-flex;
  4.   display: -ms-flexbox;
  5.   display: flex;
  6.   -webkit-box-align: center;
  7.   -webkit-align-items: center;
  8.       -ms-flex-align: center;
  9.           align-items: center;
  10. }

  11. .slider_box_icon {
  12.   display: block;
  13.   width: 35px;
  14.   height: 35px;
  15. }
  16. .slider_box_bar {
  17.   position: relative;
  18.   margin: 0 10px;
  19.   padding: 33px 0;
  20.   -webkit-box-flex: 1;
  21.   -webkit-flex: 1;
  22.       -ms-flex: 1;
  23.           flex: 1;
  24. }
  25. .slider_box_slider {
  26.   position: absolute;
  27.   height: 33px;
  28.   top: 0;
  29.   left: 0;
  30.   z-index: 1;
  31.   -webkit-transform: translate(-50%, 0);
  32.       -ms-transform: translate(-50%, 0);
  33.           transform: translate(-50%, 0);
  34. }

  35. .slider_box_slider_touch {
  36.   position: absolute;
  37.   left: 50%;
  38.   bottom: -11px;
  39.   margin-left: -8px;
  40.   width: 20px;
  41.   height: 20px;
  42.   border-radius: 15px;
  43.   background-color: white;
  44.     border: 1px solid rgb(195, 194, 194);
  45. }
  46. .slider_box_line {
  47.   position: relative;
  48.   height: 4px;
  49.   border-radius: 4px;
  50.   background-color: rgb(195, 194, 194);
  51. }
  52. .slider_box_line_fill {
  53.   position: absolute;
  54.   top: 0;
  55.   left: 0;
  56.   height: 4px;
  57.   background-color: gold;
  58.   border-radius: 4px;
  59. }
复制代码

  JavaScript 调用:
  1.    var bar = new Bar({ $id: "lightsider", stepCount: 100, min: 0, $alpha: "alpha" });
复制代码

  stepCount相当于最大长度。$alpha用来显示亮度值。效果如下


  主要的原理就是监听 touchmove事件,通过移动的pageX减去圆点左边的位置除以滑动条的总长度得到比率,最后换算成step
  1.    bar.leftDis = bar.barNode.offset().left;
  2.         bar.sliderWidth = bar.barNode.width();

  3.         bar.barNode.on("touchmove", function (e) {
  4.             e.preventDefault();
  5.             // bar.parentNode.addClass("on");
  6.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  7.             var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
  8.             bar.refreshPos(ratio);
  9.         });
复制代码

  如果是竖着的滑动条呢? 暂且定义一个UpBar对象:
1.gif

  1. var UpBar = function (opt) {
  2.     var defaults = {
  3.         $id: "", // 进度条dom节点id
  4.         min: 1, // 刻度最小值
  5.         stepCount: 5, // 刻度步数
  6.         step: 1, // 刻度步长
  7.         $alpha: "",//显示亮度的id
  8.         touchEnd: function () { } // 拖动完成回调
  9.     };
  10.     this.option = $.extend(defaults, opt);
  11.     this.barNode = $("#" + this.option.$id);
  12.     this.parentNode = this.barNode.parents(".J_slider_box");
  13.     this.sliderNode = this.barNode.find(".J_slider");
  14.     this.fillNode = this.barNode.find(".J_fill");
  15.     this.valNode = this.barNode.find(".J_value");
  16.     this.val = this.option.min;
  17.     // this.valNode.text(this.val);

  18.     this._init();
  19.     return this;
  20. }
  21. UpBar.prototype = {
  22.     /**
  23.      * 根据比例值来重新渲染进度条的位置
  24.      * @param ratio 取值:0~1
  25.      */
  26.     refreshPos: function (ratio) {
  27.         if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
  28.             return;
  29.         }
  30.         // 根据触点位置更新进度条
  31.         var percentage = ratio * 100;
  32.         this.sliderNode.css("bottom", percentage + "%");
  33.         this.fillNode.css("height", percentage + "%");

  34.         var unit = 1 / this.option.stepCount,
  35.             halfUnit = unit / 2,
  36.             a = Math.floor(ratio / unit),
  37.             b = ratio % unit,
  38.             index = a + (b < halfUnit ? 0 : 1);
  39.         this.val = this.option.min + index * this.option.step;
  40.         if (this.option.$alpha) {
  41.             $("#" + this.option.$alpha).html(this.val);
  42.         } else {
  43.           //  this.valNode.text(this.val);
  44.         }
  45.     },
  46.     /**
  47.      * 设置指定的进度值
  48.      */
  49.     setVal: function (val) {
  50.         var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
  51.         this.refreshPos(ratio);
  52.     },
  53.     _init: function () {
  54.         var bar = this;
  55.         if (!(bar.barNode.height() > 0)) {
  56.             setTimeout(function () {
  57.                 bar._init();
  58.             }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
  59.             return;
  60.         }
  61.         bar.topDis = bar.barNode.offset().top;
  62.         bar.sliderHeight = bar.barNode.height();

  63.         bar.barNode.on("touchmove", function (e) {
  64.             e.preventDefault();
  65.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  66.             var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
  67.             bar.refreshPos(ratio);
  68.         });

  69.         bar.barNode.on("touchend", function (e) {
  70.             e.preventDefault();
  71.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  72.             var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
  73.             bar.refreshPos(ratio);
  74.             bar.option.touchEnd(bar.val);
  75.         });

  76.         bar.refreshPos(this.val);

  77.     }
  78. };
复制代码

  css:
  1. .slider_box_slider_up {
  2.   position: absolute;
  3.   width: 33px;
  4.   top: 0;
  5.   right: -20px;
  6.   z-index: 1;
  7.   -webkit-transform: translate(-50%, 0);
  8.       -ms-transform: translate(-50%, 0);
  9.           transform: translate(-50%, 0);
  10. }
  11. .slider_box_slider_touch_up {
  12.   position: absolute;
  13.   width: 20px;
  14.   height: 20px;
  15.     bottom: -10px;
  16.     left: 0;
  17.   border-radius: 15px;
  18.   background-color: white;
  19.     border: 1px solid rgb(195, 194, 194);
  20. }
  21. .slider_box_line_up {
  22.   width: 4px;
  23.     height: 100%;
  24.   border-radius: 4px;
  25.   position: relative;
  26.     margin: 0 auto;
  27.   background-color: rgb(195, 194, 194);
  28. }
  29. .slider_box_line_fill_up {
  30.   position: absolute;
  31.   bottom:0;
  32.   left: 0;
  33.   width: 4px;
  34.   background-color: gold;
  35.   border-radius: 4px;
  36. }
复制代码

  html:
  1. <div class="soundBar">
  2.                 <div id="soundBar" class="slider_box_up J_slider_box">
  3.                     <div class="slider_box_line_up">
  4.                         <span class="slider_box_line_fill_up J_fill" style="height: 0%"></span>
  5.                     </div>
  6.                     <div class="slider_box_slider_up J_slider" style="bottom: 0%">
  7.                         <i class="slider_box_slider_label J_value"></i>
  8.                         <i class="slider_box_slider_touch_up"></i>
  9.                     </div>
  10.                 </div>
  11.             </div>
复制代码

  调用:
  1.   var bar = new UpBar({ $id: "soundBar", stepCount: 100, min: 0 });
复制代码

  效果如下:
1.png

  主要的区别是left-->bottom,width-->height,另外一个因为y轴是以左上角为0,0的,touch.pageY越往下越大,所以算比率的时候用要这样:
  1. bar.topDis = bar.barNode.offset().top;
  2.         bar.sliderHeight = bar.barNode.height();
  3.         bar.barNode.on("touchmove", function (e) {
  4.             e.preventDefault();
  5.             var touch = e.changedTouches ? e.changedTouches[0] : e;
  6.             var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
  7.             bar.refreshPos(ratio);
  8.         });
复制代码

  有兴趣也可以合二为一。

相关帖子

发表于 2017-1-3 15:28:20 | 显示全部楼层
个人觉得js是一种解释性语言,它提供了一个非常方便的开发过程,不需要编译,js与HTML标识结合在一起,从而方便用户的使用操作。
使用道具 举报

回复

发表于 2017-1-3 15:28:20 | 显示全部楼层
鄙视楼下的顶帖没我快,哈哈
使用道具 举报

回复

发表于 2017-1-3 15:28:21 | 显示全部楼层
Very Good!
使用道具 举报

回复

发表于 2017-1-3 15:28:22 | 显示全部楼层
无论是不是沙发都得回复下
使用道具 举报

回复

发表于 2017-1-3 15:28:22 | 显示全部楼层
经常看到”白青青“发帖,辛苦了
使用道具 举报

回复

发表于 2017-1-3 15:28:23 | 显示全部楼层
JavaScript依赖于浏览器本身,与操作环境无关,只要计算机能运行浏览器,并支持JavaScript的浏览器,就可正确执行,从而实现了“编写一次,走遍天下”的梦想。
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部