首页 > 代码库 > 【JavaScript吉光片羽】--- 滑动条

【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="width: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);        });

有兴趣也可以合二为一。

 

【JavaScript吉光片羽】--- 滑动条