【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);
}
};
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:;
-webkit-flex:;
-ms-flex:;
flex:;
}
.slider_box_slider {
position: absolute;
height: 33px;
top:;
left:;
z-index:;
-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:;
left:;
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);
}
};
css:
.slider_box_slider_up {
position: absolute;
width: 33px;
top:;
right: -20px;
z-index:;
-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:;
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:;
left:;
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事件。
【JavaScript吉光片羽】--- 滑动条的更多相关文章
- 【JavaScript吉光片羽】遭遇IE8
最初对做兼容性的认知只停留在UI层面,但其实UI层面都还好,因为毕竟你可以直接看得见现象,更为重要的是在JavaScript层面,因为这个部分涉及到功能性,前者最多是体验性的问题.下面扯一下这几天遇到 ...
- 【吉光片羽】js横向滚动与浮动导航
1.横向滚动,这个方法是见过最简洁的了. #demo { background: #FFF; overflow: hidden; border: 1px dashed #CCC; width: 117 ...
- 【吉光片羽】ie6兼容性的几个点
1.浮动换行.自己写个导航,li向左浮动,到ie6下全部错开了. --> 还是在现有bootstrap框架的基础上修改样式保险一些. <div id="mymenu" ...
- 【吉光片羽】奇怪的Bug-细节的问题
这几天用Winform开发了一个小界面,遇到几个奇怪的问题,记录一下. 1.背景图片漏光. 当时很是奇怪,以为是图片的问题,让美工重新发,改成jpg也都存在.很是奇怪,原图这个地方肉眼看是不透明的,而 ...
- 【吉光片羽】MVC 导出Word的两种方式
1.直接将Html转成Word.MVC自带FileResult很好用.Html中我们也可以嵌入自己的样式. html: <div id="target"> <st ...
- 【吉光片羽】之 Web API
1.在asp项目中直接添加apiController,需要新增Global.asax文件.再增加一个webapiConfig,如果需要访问方式为"api/{controller}/{acti ...
- 实现滑动条与表单中的input中的value交互
最近在写一个考试系统的项目,遇到一些比较有意思的小知识,在这里分享给大家 下面是一个滑动条与input中的value值的交互,即滑动条的颜色会跟随给定input的value值实时变化,虽然表单中的ra ...
- easyui源码翻译1.32--Slider(滑动条)
前言 使用$.fn.slider.defaults重写默认值对象.下载该插件翻译源码 滑动条允许用户从一个有限的范围内选择一个数值.当滑块控件沿着轨道移动的时候,将会显示一个提示来表示当前值.用户可以 ...
- JavaScript初学者应知的24条最佳实践(译)
原文:24 JavaScript Best Practices for Beginners 译者:youngsterxyf (注:阅读原文的时候没有注意发布日期,觉得不错就翻译了,翻译到JSON.pa ...
随机推荐
- 通过adb方式给安卓手机截图的cmd批处理文件
@echo off rem 通过adb方式截图rem 需要安装adb ,一般安装了android sdk 默认带了adb ,路径为sdk目录的android-sdk\platform-toolsr ...
- LINUX篇,设置MYSQL远程访问实用版
每次设置root和远程访问都容易出现问题, 总结了个通用方法, 关键在于实用 step1: # mysql -u root mysql mysql> Grant all privileges o ...
- 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇
什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...
- Azure Service Fabric 开发环境搭建
微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...
- Appium移动自动化框架
引言:Appium 是一个移动端自动化测试开源工具,可以针对不同的平台用一套API来编写测试用例.本文对Appium自动化测试框架的功能进行了概括. 本文选自<软件自动化测试开发>. Ap ...
- FILE文件流的中fopen、fread、fseek、fclose的使用
FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...
- App解读
一直不懂别人口中说的原生开发.混合式开发.今天突然看了一篇文章讲解的是什么叫做原生App?移动 Web App?混合APP?分享给大家. 原生App是专门针对某一类移动设备而生的,它们都是直接安装到设 ...
- iOS网络4——Reachability检测网络状态
一.整体介绍 前面已经介绍了网络访问的NSURLSession.NSURLConnection,还有网页加载有关的webview,基本满足通常的网络相关的开发. 其实在网络开发中还有比较常用的就是网络 ...
- maven 快照
大型应用软件一般由多个模块组成,一般它是多个团队开发同一个应用程序的不同模块,这是比较常见的场景.例如,一个团队正在对应用程序的应用程序,用户界面项目(app-ui.jar:1.0) 的前端进行开发, ...
- css实现文本框和下拉框结合的案例
html 代码部分 <div id="list-name-input" class="list-name-input"> <select ty ...