(做真的烂设计,写真的烂代码,能用就行)
实现流程
- 通过document.createElement(‘div’)创建滑动条的相关部件:外框或容器(out_bar),内框或进度条(inner_bar),滑块(slider),三者关系:外框 为 内框父级,内框 为 滑块父级;
- 通过 obj.appendChild( out_bar ) 或 objChlid.parentNode.insertBefore(out_bar, objChlid)将进度条插入指定位置
- 滑动条的滑动:
- 3.1 设置进度条长度 :
长度 通过设置inner_bar.style.width (水平滑动条)或者inner_bar.style.height (垂直滑动条)实现 - 3.2 设置进度条在外框中的位置:
位置 通过设置 style.marginLeft 或者 style.marginTop 来设置 inner_bar 在其父级元素内部的偏移量;具体偏移量——水平滑动条无需设置inner_bar的偏移量,垂直滑动条则设置inner_bar.style.marginTop
pageY 为鼠标到文档最顶部的距离(包括文档不可见的滚动区域大小)
- 3.1 设置进度条长度 :
其它说明可看js代码中的注释
使用示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
border: 0;
}
<style/>
</head>
<script src="滑动条.js" type="text/javascript" charset="utf-8"></script>
<body>
<div id="out" style="margin: 30px;"></div>
</body>
<script type="text/javascript">
//创建滑动条对象
//参数: 进度条 width -->400,height -->20,滑块 width/height-->30
sliderBar1=new sliderBar(400,20,30)
// sliderBar1=new sliderBar(10,400,30)
//将滑动条追加到document.getElementById('out')成为子节点
sliderBar1.appedTo(document.getElementById('out'))
// sliderBar1.insetBefore(document.getElementById('out'))
sliderBar1.setValue(0.6) //滑动条当前百分比(位置)
console.log(sliderBar1.getValue())
/* 进度条外框:id --- '#out_bar'
内框:id --- '#inner_bar'
滑块:id --- '#slider'
id可用于在css中定义进度条相关样式
注意:因为已在js代码中通过style.width/height/background 属性
设置了相关样式,所以在css中设置这些相关样式不会生效(优先级低于通过js设置的样式),
如需修改请看下文中的相关函数(方法)
*/
/* sliderBar1.out_bar 获取外框对象 一个div
sliderBar1.inner_bar 获取内框对象(进度条中间部分)一个div
sliderBar1.slider 获取滑块对象 一个div
*/
// sliderBar1.setDirection(1) 设置滑动方式 水平0 或 垂直1
// sliderBar1.setOverflow(1) 滑块滑动至首尾时是否允许溢出
// sliderBar1.prohibitSlideOutside() 禁止在滑动条外拖拽
// sliderBar1.setRadius('1px','59%','5px','4px') 设置滑动条圆角
// sliderBar1.setSliderRadius('50%') 设置滑块圆角
// sliderBar1.showSliider(0) 滑块是否可见
/*
*传入一个样式对象设置css样式
sliderBar1.setSliderStyle({'background':'yellow',border:'1px solid green','width':'50px'}); 滑块
sliderBar1.setOut_barStyle(···); 设置外框样式
sliderBar1.setInner_barStyle(···); 设置内框(进度条)样式
*/
</script>
</html>
滑动条 js代码:
function sliderBar(width, height, radius) {
w = '' + width + "px"
h = '' + height + "px"
r = '' + radius + 'px'
//创建滑动条 (组件)元素
let out_bar = document.createElement("div") //容器(外框)
let inner_bar = document.createElement("div") //进度条 (内框)
let slider = document.createElement("div") //滑块
//添加 id 方便用css 操作样式
out_bar.setAttribute("id", "out_bar")
inner_bar.setAttribute('id', 'inner_bar')
slider.setAttribute('id', 'slider')
//为 new 对象添加相关节点对象使外部可以访问
this.out_bar = out_bar
this.inner_bar = inner_bar
this.slider = slider
out_bar.appendChild(inner_bar)
inner_bar.appendChild(slider)
let percent = 0
this.value = percent
let direction = 0 //水平 0 或者 垂直 1
let slidOutside = 1 //是否允许在滑动条外滑动 否0 或者 是1
let overflow = 0 //是否允许滑块溢出滑动条外框
//初始化滑动条css样式--------↓
out_bar.style.width = w;
out_bar.style.height = h;
out_bar.style.background = "#e7e7e7";
out_bar.style.borderRadius = "5px"
if (w >= h) {//初步判断水平还是垂直
inner_bar.style.width = 0;
inner_bar.style.height = h;
} else {
inner_bar.style.width = w;
inner_bar.style.height = 0;
}
inner_bar.style.background = "#B6B6B6";
inner_bar.style.float = "left";
inner_bar.style.borderRadius = "5px"
slider.style.width = r;
slider.style.height = r;
slider.style.background = "rgba(0, 147, 220, 0.5)";
slider.style.borderRadius = "50%"
//初始化滑动条css样式--------↑
//通过比较w和h的值自动判断 水平还是垂直滑动条
if(w>=h){
direction=0
}else{
direction=1
}
//设置滑块css样式
this.setSliderStyle=function(obj){
for(tmp in obj){
let key=tmp;
if(key.indexOf('-')!=-1){
key=key.replace('-','').replace(key[key.indexOf('-')+1],key[key.indexOf('-')+1].toUpperCase())
}
this.slider.style[key]=obj[tmp]
}
}
this.setOut_barStyle=function(obj){
for(tmp in obj){
let key=tmp;
if(key.indexOf('-')!=-1){
key=key.replace('-','').replace(key[key.indexOf('-')+1],key[key.indexOf('-')+1].toUpperCase())
}
this.out_bar.style[key]=obj[tmp]
}
}
this.setInner_barStyle=function(obj){
for(tmp in obj){
let key=tmp;
if(key.indexOf('-')!=-1){
key=key.replace('-','').replace(key[key.indexOf('-')+1],key[key.indexOf('-')+1].toUpperCase())
}
this.inner_bar.style[key]=obj[tmp]
}
}
//设置滑动条圆角
this.setRadius=function(x,y,z,w){
let radius=str(x)+' '+str(y)+' '+str(z)+' '+str(w)
out_bar.style.borderRadius=radius
inner_bar.style.borderRadius=radius
function str(tmp){
if((''+tmp).indexOf('%')!=-1 || (''+tmp).indexOf('px')!=-1)
return tmp
else if(typeof tmp == 'number' ){
return ''+tmp+'px'
}else{
return ''
}
}
return str(x)+' '+str(y)+' '+str(z)+''+str(w)
}
//设置滑块圆角
this.setSliderRadius=function(x,y,z,w){
let radius=str(x)+' '+str(y)+' '+str(z)+' '+str(w)
slider.style.borderRadius=radius
function str(tmp){
if((''+tmp).indexOf('%')!=-1 || (''+tmp).indexOf('px')!=-1)
return tmp
else if(typeof tmp == 'number' ){
return ''+tmp+'px'
}else{
return ''
}
}
return str(x)+' '+str(y)+' '+str(z)+''+str(w)
}
//是否展示滑块
this.showSliider=function(num){
if(num==0){
slider.style.display='none';
}else{
slider.style.display='block';
}
}
this.getValue = function() {
// return this.value
return percent
}
//设置百分比
this.setValue = function (value) {
if (value < 0) {
this.value = 0
} else if (value > 1) {
this.value = 1
} else {
this.value = value
}
if(direction==0){
inner_bar.style.width=''+(out_bar.clientWidth * this.value)+'px'
}else{
inner_bar.style.height=''+(out_bar.clientHeight * this.value)+'px'
}
updateInner_bar()
}
//刷新进度条状态(位置)
function updateInner_bar(){
if(direction==0){ //水平
inner_bar.marginLeft = inner_bar.offsetWidth+'px';
//刷新滑动条百分比值
percent = inner_bar.offsetWidth / parseInt(out_bar.clientWidth)
}else{ //垂直
inner_bar.style.marginTop = (out_bar.clientHeight-inner_bar.offsetHeight)+'px';
//刷新滑动条百分比值
percent = inner_bar.offsetHeight / parseInt(out_bar.clientHeight)
}
updateSlider()
}
//刷新滑块状态(位置)
function updateSlider(){
if(direction==0){
//滑块位置
inner_bar_width = parseInt(inner_bar.offsetWidth)
if (overflow == 1) { //指滑块可以超出两端的情况-----允许滑块溢出滑动条左右外框时
slider.style.marginLeft = inner_bar.offsetWidth - slider.offsetWidth / 2 + 'px'
} else if (inner_bar_width <= slider.offsetWidth / 2) { //最左端时
slider.style.marginLeft = 0
} else if (inner_bar_width + slider.offsetWidth / 2 >= out_bar.clientWidth) { //最右端时
slider.style.marginLeft = out_bar.offsetWidth - slider.offsetWidth
} else { //中间
slider.style.marginLeft = '' + inner_bar.clientWidth - slider.offsetWidth / 2 + 'px'
}
//刷新滑动条百分比值
// percent = inner_bar_width / parseInt(out_bar.clientWidth)
}else{
//滑块位置
inner_bar_height = parseInt(inner_bar.offsetHeight)
if (overflow == 1) {
//允许滑块溢出滑动条上下外框时
slider.style.marginTop = '-'+slider.offsetHeight/2+'px'
} else if (inner_bar_height >= out_bar.clientHeight - slider.offsetHeight/2) {
slider.style.marginTop = '-' + (out_bar.clientHeight- inner_bar.offsetHeight) +'px'
} else if (inner_bar_height <= slider.offsetWidth/2) {
slider.style.marginTop = '-' + (slider.offsetWidth - inner_bar.offsetHeight) + 'px'
} else {
slider.style.marginTop = -slider.offsetHeight/2 +'px'
}
}
}
//将滑动条添加至 element
this.appedTo = function(element) {
element.appendChild(this.out_bar)
toCenter()
updateInner_bar()
}
//将滑动条插入到element前面(兄弟节点)
this.insetBefore = function(element) {
element.parentNode.insertBefore(this.out_bar, element)
toCenter()
}
//是否允许在滑动条外滑动 否0 或者 是1
this.prohibitSlideOutside = function() {
out_bar.onmouseleave = function() {
document.onmousemove = null
return false
}
}
//是否允许滑块溢出滑动条外框
this.setOverflow=function(num){
if(num == 1){
overflow = 1
if(direction == 0){
slider.style.marginLeft=''+(inner_bar.offsetWidth-slider.offsetWidth/2)+'px'
}else{
slider.style.marginTop=''+(inner_bar.offsetHeight-slider.offsetHeight/2)+'px'
}
return
}
overflow = 0
}
//设置滑动条滑动状态 水平或者垂直 默认水平
this.setDirection = function(num) {
if (num == 1) {
direction = 1
// slider.style.marginTop = (out_bar.clientHeight - inner_bar.offsetHeight) +'px'
}else{
direction = 0
}
updateInner_bar()
toCenter()
}
//滑动条内部元素居中
function toCenter() {
if (direction == 0) {
//inner_bar垂直居中
inner_bar.style.marginTop = "" + (out_bar.clientHeight / 2 - inner_bar.offsetHeight / 2) + 'px'
//滑块垂直居中
slider.style.marginTop = "" + (inner_bar.offsetHeight / 2 - slider.offsetHeight / 2) + "px"
} else {
//inner_bar水平居中
inner_bar.style.marginLeft = "" + (out_bar.clientWidth / 2 - inner_bar.offsetWidth / 2) + 'px'
//滑块居中
slider.style.marginLeft = "" + (inner_bar.offsetWidth / 2 - slider.offsetWidth / 2) + "px"
}
}
//定义单击或滑动滑动条时修改的方法 ----水平方向
function move1(event) {
//移动端或者电脑端
event = event.touches ? event.touches[0] : event
//鼠标相对窗口位置
//event.pageX + document.body.scrollLeft:窗口有滚动条时鼠标相对窗口最顶部侧(包括看不见部分)的位置
var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
//进度条外框相对窗口偏移量
var offX = out_bar.offsetLeft
//进度条inner_bar相对外框偏移量(width) 外框有border值时会影响偏移量
var x = pageX - offX - out_bar.clientLeft
/* 因为后续代码中允许在选中滑块时可以在滑动条外继续移动(document.onmousemove = move)
,所以需避免 负值 和 超过滑动条最大值*/
var out_bar_width = out_bar.clientWidth
if (x > out_bar_width) {
x = out_bar_width
} else if (x < 0) {
x = 0
}
//修改进度条inner_bar长度
inner_bar.style.width = x + 'px';
//滑块位置 updateSlider()
inner_bar_width = inner_bar.offsetWidth
if (overflow == 1) {
slider.style.marginLeft = inner_bar.offsetWidth - slider.offsetWidth / 2 + 'px' //允许滑块溢出滑动条左右外框时
} else if (inner_bar_width <= slider.offsetWidth / 2) { //最左端时
slider.style.marginLeft = 0
} else if (inner_bar_width + slider.offsetWidth / 2 >= out_bar.clientWidth) { //最右端时
slider.style.marginLeft = '' + (out_bar.clientWidth - slider.offsetWidth) + 'px'
} else { //中间
slider.style.marginLeft = '' + (inner_bar.clientWidth - slider.offsetWidth / 2) + 'px'
}
//刷新滑动条百分比值
percent = inner_bar_width / out_bar.clientWidth
return false
}
//定义单击或滑动滑动条时修改的方法----垂直方向
function move2(event) {
//移动端或者电脑端
event = event.touches ? event.touches[0] : event
//鼠标相对窗口位置
//event.pageX + document.body.scrollLeft:窗口有滚动条时鼠标相对窗口最左侧(包括看不见部分)的位置
var pageY = event.pageY || event.clientY + document.body.scrollTop;
//进度条外框相对窗口偏移量
var offY = out_bar.offsetTop
//进度条inner_bar相对外框偏顶部移量 外框有border值时会影响偏移量
var y = pageY - offY - out_bar.clientTop
/* 因为后续代码中允许在选中滑块时可以在滑动条外继续移动(document.onmousemove = move)
,需避免负值和超过滑动条最大值*/
var out_bar_height = out_bar.clientHeight
if (y >= out_bar_height) {
y = out_bar_height
inner_bar.style.marginTop = out_bar_height + 'px'
} else if (y <= 0) {
y = 0;
inner_bar.style.marginTop = 0
} else {
inner_bar.style.marginTop = '' + y + 'px'
}
//修改进度条inner_bar长度
inner_bar.style.height = '' + (out_bar_height - y) + 'px'
//滑块位置 updateSlider()
inner_bar_height = inner_bar.offsetHeight
if (overflow == 1) {
//允许滑块溢出滑动条上下外框时
slider.style.marginTop = '-'+slider.offsetHeight/2+'px'
} else if (inner_bar_height >= out_bar.clientHeight - slider.offsetHeight/2) {
slider.style.marginTop = '-' + (out_bar.clientHeight- inner_bar.offsetHeight) +'px'
} else if (inner_bar_height <= slider.offsetWidth/2) {
slider.style.marginTop = '-' + (slider.offsetWidth - inner_bar.offsetHeight) + 'px'
} else {
slider.style.marginTop = -slider.offsetHeight/2 +'px'
}
//滑动条百分比
percent = inner_bar_height / out_bar.clientHeight
return false
}
//根据滑动条方向选择滑动方式(水平、垂直)
function move(e) {
if (direction == 1) {
move2(e)
return
}
move1(e)
}
function cancel() {
// 取消鼠标移动事件
document.ontouchmove = null
document.onmousemove = null
// 取消鼠标抬起事件
document.onmouseup = null
return false
}
//--------------------------此处开始触发事件----------------------------
//单击修改滑动条位置
out_bar.onmousedown = function(e) {
move(e);
document.onmousemove = move
document.onmouseup = cancel
// console.log("百分比"+percent)
return false
}
//电脑端
slider.onmousedown = function() {
document.onmousemove = move
document.onmouseup = cancel
return false
}
//移动端
slider.ontouchstart = function(e) {
// --onmousemover--高频事件--
document.ontouchmove = move
document.onmouseup = cancel
return false
}
}