一条可自定义的滑动条(js)

本文展示了如何使用JavaScript和CSS创建一个自定义滑动条,包括创建滑动条的各个组件,设置样式,以及处理滑动事件来改变进度。代码示例详细解释了滑动条的工作原理和交互逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(做真的烂设计,写真的烂代码,能用就行)

实现流程

  1. 通过document.createElement(‘div’)创建滑动条的相关部件:外框或容器(out_bar),内框或进度条(inner_bar),滑块(slider),三者关系:外框 为 内框父级,内框 为 滑块父级;
  2. 通过 obj.appendChild( out_bar ) 或 objChlid.parentNode.insertBefore(out_bar, objChlid)将进度条插入指定位置
  3. 滑动条的滑动:
    • 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 为鼠标到文档最顶部的距离(包括文档不可见的滚动区域大小)

其它说明可看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
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值