zoukankan      html  css  js  c++  java
  • 【JavaScript吉光片羽】--- 滑动条

    灯光的亮度控制需要一个滑动条,先借用lamp源码中Bar:

    var Bar = function (opt) {
        var defaults = {
            $id: "", // 进度条dom节点id
            min: 1, // 刻度最小值
            stepCount: 5, // 刻度步数
            step: 1, // 刻度步长
            $alpha: "",//显示亮度的id
            touchEnd: function () { } // 拖动完成回调
        };
        this.option = $.extend(defaults, opt);
        this.barNode = $("#" + this.option.$id);
        this.parentNode = this.barNode.parents(".J_slider_box");
        this.sliderNode = this.barNode.find(".J_slider");
        this.fillNode = this.barNode.find(".J_fill");
        this.valNode = this.barNode.find(".J_value");
        this.val = this.option.min;
        // this.valNode.text(this.val);
    
        this._init();
        return this;
    }
    Bar.prototype = {
        /**
         * 根据比例值来重新渲染进度条的位置
         * @param ratio 取值:0~1
         */
        refreshPos: function (ratio) {
            if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
                return;
            }
            // 根据触点位置更新进度条
            var percentage = ratio * 100;
            this.sliderNode.css("left", percentage + "%");
            this.fillNode.css("width", percentage + "%");
    
            var unit = 1 / this.option.stepCount,
                halfUnit = unit / 2,
                a = Math.floor(ratio / unit),
                b = ratio % unit,
                index = a + (b < halfUnit ? 0 : 1);
            this.val = this.option.min + index * this.option.step;
            if (this.option.$alpha) {
                $("#" + this.option.$alpha).html(this.val);
            } else {
                this.valNode.text(this.val);
            }
        },
        /**
         * 设置指定的进度值
         */
        setVal: function (val) {
            var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
            this.refreshPos(ratio);
        },
        _init: function () {
            var bar = this;
            if (!(bar.barNode.width() > 0)) {
                setTimeout(function () {
                    bar._init();
                }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
                return;
            }
            bar.leftDis = bar.barNode.offset().left;
            bar.sliderWidth = bar.barNode.width();
    
            bar.barNode.on("touchmove", function (e) {
                e.preventDefault();
                // bar.parentNode.addClass("on");
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
            });
    
            bar.barNode.on("touchend", function (e) {
                e.preventDefault();
                //bar.parentNode.removeClass("on");
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
                bar.option.touchEnd(bar.val);
            });
    
            bar.refreshPos(this.val);
    
        }
    };
    View Code

    html:

         <div class="lightsider">
                    <div id="lightsider" class="slider_box J_slider_box">
                        <i class="slider_box_icon icon dark"></i>
                        <div id="lightBar" class="slider_box_bar">
                            <div class="slider_box_slider J_slider" style="left:0%">
                                <p class="slider_box_slider_label J_value"></p>
                                <i class="slider_box_slider_touch"></i>
                            </div>
                            <div class="slider_box_line">
                                <span class="slider_box_line_fill J_fill" style="0%"></span>
                            </div>
                        </div>
                        <i class="slider_box_icon icon light"></i>
                    </div>
                </div>  

    css:

    .slider_box {
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-align: center;
      -webkit-align-items: center;
          -ms-flex-align: center;
              align-items: center;
    }
    
    .slider_box_icon {
      display: block;
      width: 35px;
      height: 35px;
    }
    .slider_box_bar {
      position: relative;
      margin: 0 10px;
      padding: 33px 0;
      -webkit-box-flex: 1;
      -webkit-flex: 1;
          -ms-flex: 1;
              flex: 1;
    }
    .slider_box_slider {
      position: absolute;
      height: 33px;
      top: 0;
      left: 0;
      z-index: 1;
      -webkit-transform: translate(-50%, 0);
          -ms-transform: translate(-50%, 0);
              transform: translate(-50%, 0);
    }
    
    .slider_box_slider_touch {
      position: absolute;
      left: 50%;
      bottom: -11px;
      margin-left: -8px;
      width: 20px;
      height: 20px;
      border-radius: 15px;
      background-color: white;
        border: 1px solid rgb(195, 194, 194);
    }
    .slider_box_line {
      position: relative;
      height: 4px;
      border-radius: 4px;
      background-color: rgb(195, 194, 194);
    }
    .slider_box_line_fill {
      position: absolute;
      top: 0;
      left: 0;
      height: 4px;
      background-color: gold;
      border-radius: 4px;
    }

    JavaScript 调用:

       var bar = new Bar({ $id: "lightsider", stepCount: 100, min: 0, $alpha: "alpha" });

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

    主要的原理就是监听 touchmove事件,通过移动的pageX减去圆点左边的位置除以滑动条的总长度得到比率,最后换算成step

       bar.leftDis = bar.barNode.offset().left;
            bar.sliderWidth = bar.barNode.width();
    
            bar.barNode.on("touchmove", function (e) {
                e.preventDefault();
                // bar.parentNode.addClass("on");
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio = (touch.pageX - bar.leftDis) / bar.sliderWidth;
                bar.refreshPos(ratio);
            });

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

    var UpBar = function (opt) {
        var defaults = {
            $id: "", // 进度条dom节点id
            min: 1, // 刻度最小值
            stepCount: 5, // 刻度步数
            step: 1, // 刻度步长
            $alpha: "",//显示亮度的id
            touchEnd: function () { } // 拖动完成回调
        };
        this.option = $.extend(defaults, opt);
        this.barNode = $("#" + this.option.$id);
        this.parentNode = this.barNode.parents(".J_slider_box");
        this.sliderNode = this.barNode.find(".J_slider");
        this.fillNode = this.barNode.find(".J_fill");
        this.valNode = this.barNode.find(".J_value");
        this.val = this.option.min;
        // this.valNode.text(this.val);
    
        this._init();
        return this;
    }
    UpBar.prototype = {
        /**
         * 根据比例值来重新渲染进度条的位置
         * @param ratio 取值:0~1
         */
        refreshPos: function (ratio) {
            if (ratio >= 1 || ratio < 0) { // 等于1时,js的%取值有问题,故排除
                return;
            }
            // 根据触点位置更新进度条
            var percentage = ratio * 100;
            this.sliderNode.css("bottom", percentage + "%");
            this.fillNode.css("height", percentage + "%");
    
            var unit = 1 / this.option.stepCount,
                halfUnit = unit / 2,
                a = Math.floor(ratio / unit),
                b = ratio % unit,
                index = a + (b < halfUnit ? 0 : 1);
            this.val = this.option.min + index * this.option.step;
            if (this.option.$alpha) {
                $("#" + this.option.$alpha).html(this.val);
            } else {
              //  this.valNode.text(this.val);
            }
        },
        /**
         * 设置指定的进度值
         */
        setVal: function (val) {
            var ratio = (val - this.option.min) / (this.option.step * this.option.stepCount);
            this.refreshPos(ratio);
        },
        _init: function () {
            var bar = this;
            if (!(bar.barNode.height() > 0)) {
                setTimeout(function () {
                    bar._init();
                }, 100); // 直到vm渲染完成之后才能取得正确的dom高宽
                return;
            }
            bar.topDis = bar.barNode.offset().top;
            bar.sliderHeight = bar.barNode.height();
    
            bar.barNode.on("touchmove", function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
            });
    
            bar.barNode.on("touchend", function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
                bar.option.touchEnd(bar.val);
            });
    
            bar.refreshPos(this.val);
    
        }
    };
    View Code

    css:

    .slider_box_slider_up {
      position: absolute;
      width: 33px;
      top: 0;
      right: -20px;
      z-index: 1;
      -webkit-transform: translate(-50%, 0);
          -ms-transform: translate(-50%, 0);
              transform: translate(-50%, 0);
    }
    .slider_box_slider_touch_up {
      position: absolute;
      width: 20px;
      height: 20px;
        bottom: -10px;
        left: 0;
      border-radius: 15px;
      background-color: white;
        border: 1px solid rgb(195, 194, 194);
    }
    .slider_box_line_up {
      width: 4px;
        height: 100%;
      border-radius: 4px;
      position: relative;
        margin: 0 auto;
      background-color: rgb(195, 194, 194);
    }
    .slider_box_line_fill_up {
      position: absolute;
      bottom:0;
      left: 0;
      width: 4px;
      background-color: gold;
      border-radius: 4px;
    }

    html:

     <div class="soundBar">
                    <div id="soundBar" class="slider_box_up J_slider_box">
                        <div class="slider_box_line_up">
                            <span class="slider_box_line_fill_up J_fill" style="height: 0%"></span>
                        </div>
                        <div class="slider_box_slider_up J_slider" style="bottom: 0%">
                            <i class="slider_box_slider_label J_value"></i>
                            <i class="slider_box_slider_touch_up"></i>
                        </div>
                    </div>
                </div>

    调用:

      var bar = new UpBar({ $id: "soundBar", stepCount: 100, min: 0 });

    效果如下:

    主要的区别是left-->bottom,width-->height,另外一个因为y轴是以左上角为0,0的,touch.pageY越往下越大,所以算比率的时候用要这样:

     bar.topDis = bar.barNode.offset().top;
            bar.sliderHeight = bar.barNode.height();
            bar.barNode.on("touchmove", function (e) {
                e.preventDefault();
                var touch = e.changedTouches ? e.changedTouches[0] : e;
                var ratio =1- (touch.pageY - bar.topDis) / bar.sliderHeight;
                bar.refreshPos(ratio);
            });

    有兴趣也可以合二为一。如需要获取值,就订阅touchEnd事件。

  • 相关阅读:
    windows2000/xp运行命令全集
    IP数据包的校验和算法C#版(原)
    做系统清理的批处理
    Combox用ValueMember 之后再添加一项
    安装部署基础——Windows Application
    文件编码
    Left/right join 和inner join 区别
    应用Url重写时CSS引用问题
    数据绑定控件单选框
    算法题:水杯倒水的问题
  • 原文地址:https://www.cnblogs.com/stoneniqiu/p/6218711.html
Copyright © 2011-2022 走看看