教你用原生JS写一个滑块组件
Admin 2021-04-17 群英技术资讯 960 次浏览
滑块组件就是一个允许用户在有限区间内通过移动滑块来选择值的组件。滑块组件的应用是比较常见的,例如商品价格区间筛选,音量设置,滑块验证等等。这篇文章就给大家介绍一下用原生JS实现滑块组件,下面是实现效果,功能分析以及代码。
1、最小值为0,按照给定的最大值,生成区间范围;
2、拖动滑块移动时,显示相应的范围区间,滑块条显示对应的状态;
3、点击时,使最近的滑块移动到鼠标点击的位置。
当拖动滑块时,显示如下:
下面附上代码:
html结构,实例化滑块,可以设置当前滑块的区间范围:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>slide</title> </head> <body> <script type="module"> import Slide from "./js/Slide.js"; init(); function init(){ //参数为最大范围,不传的话默认是4000 let slide=new Slide(4200); slide.appendTo("body"); } </script> </body> </html>
Slide.js文件:完成创建滑块,拖动滑块,点击滑块的功能。
import Utils from "./Utils.js"; export default class Slide{ static styleCss=false; //最小范围 minNum=0; //最大范围 maxNum; //左边按钮的left值 leftBtnLeft=0; //右边按钮的left值 rightBtnLeft=238; constructor(_max=4000){ //最大值默认为4000 this.maxNum=_max; this.elem=this.createElem(); } createElem(){ if(this.elem) return this.elem; //创建最外层容器 let div=Utils.createE("div"); div.className="slideContainer"; div.innerHTML=`<p class="priceTxt">价格<span id="rangeText">¥${this.minNum}-${this.maxNum}</span></p> <div class="rangeContainer" id="rangeContainer"> <div class="bgRange" id="bgRange"></div> <div class="priceRange" id="priceRange"></div> <span id="leftBtn" class="leftBtn"></span> <span id="rightBtn" class="rightBtn"></span> </div>`; Utils.getIdElem(div,this); //设置样式 Slide.setStyles(); //给父元素监听mousedown事件 this.rangeContainer.addEventListener("mousedown",e=>this.mouseHandler(e)) return div; } appendTo(parent){ Utils.appendTo(this.elem,parent); } mouseHandler(e){ //注意:getBoundingClientRect()返回的结果中,width height 都是包含border的 let rect=this.rangeContainer.getBoundingClientRect(); switch (e.type) { case "mousedown": //取消鼠标快速拖动的默认事件 e.preventDefault(); this.x = e.offsetX; this.btnType=e.target.id; //如果点击的是背景条,执行rangeClick函数 if(/Range/.test(this.btnType)){ e.stopPropagation(); //点击函数 this.rangeClick(e); return; } //如果点击的是按钮,监听document鼠标移动事件 this.mouseHandlers=e=>this.mouseHandler(e); document.addEventListener("mousemove", this.mouseHandlers); document.addEventListener("mouseup", this.mouseHandlers); break; case "mousemove": let x = e.clientX - rect.x - this.x; //获取左右按钮的left值 this.leftBtnLeft=parseInt(getComputedStyle(this.leftBtn).left); this.rightBtnLeft=parseInt(getComputedStyle(this.rightBtn).left); if (this.btnType === "leftBtn") { //确定左边按钮的取值范围 if (x < 0) x = 0; if (x > this.rightBtnLeft) x = this.rightBtnLeft; this.leftBtn.style.left = x + "px"; } else if (this.btnType === "rightBtn") { //确定右边按钮的取值范围,减去1px边框 if (x < this.leftBtnLeft) x = this.leftBtnLeft; if (x > this.bgRange.offsetWidth - 2) x = this.bgRange.offsetWidth - 2; this.rightBtn.style.left = x + "px"; } //文字范围显示 this.changeRangeText(); break; case "mouseup": //移动事件监听 document.removeEventListener("mousemove", this.mouseHandlers); document.removeEventListener("mouseup", this.mouseHandlers); break; } } rangeClick(e){ //计算出鼠标点击位置的值 let click_X=e.clientX-this.rangeContainer.getBoundingClientRect().x-this.leftBtn.offsetWidth/2; //判断,如果当前点击的位置是在左边按钮的左侧、或者当左右按钮重叠时,点击的位置在按钮左侧,让左边按钮移动到鼠标点击的位置 if(Math.abs(click_X-this.leftBtnLeft)<Math.abs(click_X-this.rightBtnLeft) || (this.leftBtnLeft===this.rightBtnLeft && click_X<this.leftBtnLeft)) this.leftBtn.style.left=click_X+"px"; //否则,让右边按钮移动到鼠标点击的位置 else this.rightBtn.style.left=click_X+"px"; //获取移动后的左右按钮的left值 this.leftBtnLeft=parseInt(getComputedStyle(this.leftBtn).left); this.rightBtnLeft=parseInt(getComputedStyle(this.rightBtn).left); //文字范围显示 this.changeRangeText(); } changeRangeText(){ //计算出最小范围与最大范围的值,四舍五入 let minTxt=Math.round(this.leftBtnLeft/(this.bgRange.clientWidth-2)*this.maxNum); let maxTxt=Math.round(this.rightBtnLeft/(this.bgRange.clientWidth-2)*this.maxNum); this.rangeText.innerText=`¥${minTxt}-${maxTxt}`; //滑块颜色的改变 this.changeRangeSlide(); } changeRangeSlide(){ //滑块宽度等于左右按钮间的距离 this.priceRange.style.width=this.rightBtnLeft-this.leftBtnLeft+"px"; //滑块的left值等于左边按钮的left值 this.priceRange.style.left=this.leftBtnLeft+"px"; } static setStyles(){ if(Slide.styleCss) return; Slide.styleCss=true; Utils.insertCss(".slideContainer",{ width:"260px", height:"70px", margin:"50px" }) Utils.insertCss(".priceTxt",{ fontSize:"14px", color:"#666", marginBottom:"20px" }) Utils.insertCss(".priceTxt span",{ float:"right" }) Utils.insertCss(".rangeContainer",{ width:"260px", height:"20px", position:"relative", }) Utils.insertCss(".bgRange",{ width:"240px", height:"3px", backgroundColor:"#dedede", position:"absolute", left:"10px", top:"9px" }) Utils.insertCss(".priceRange",{ width:"240px", height:"3px", background:"#ffa800", position:"absolute", left:"10px", top:"9px" }) Utils.insertCss(".rangeContainer span",{ width: "20px", height: "20px", borderRadius:"50%", border:"1px solid #ccc", background:"#fff", position:"absolute", top:"0px", boxShadow:"2px 2px 2px #333" }) Utils.insertCss(".leftBtn",{ left:"0px" }) Utils.insertCss(".rightBtn",{ left:"238px" }) } }
Utils.js文件:是一个工具包文件。
export default class Utils{ static createE(elem,style,prep){ elem=document.createElement(elem); if(style) for(let prop in style) elem.style[prop]=style[prop]; if(prep) for(let prop in prep) elem[prop]=prep[prop]; return elem; } static appendTo(elem,parent){ if (parent.constructor === String) parent = document.querySelector(parent); parent.appendChild(elem); } static randomNum(min,max){ return Math.floor(Math.random*(max-min)+min); } static randomColor(alpha){ alpha=alpha||Math.random().toFixed(1); if(isNaN(alpha)) alpha=1; if(alpha>1) alpha=1; if(alpha<0) alpha=0; let col="rgba("; for(let i=0;i<3;i++){ col+=Utils.randomNum(0,256)+","; } col+=alpha+")"; return col; } static insertCss(select,styles){ if(document.styleSheets.length===0){ let styleS=Utils.createE("style"); Utils.appendTo(styleS,document.head); } let styleSheet=document.styleSheets[document.styleSheets.length-1]; let str=select+"{"; for(var prop in styles){ str+=prop.replace(/[A-Z]/g,function(item){ return "-"+item.toLocaleLowerCase(); })+":"+styles[prop]+";"; } str+="}" styleSheet.insertRule(str,styleSheet.cssRules.length); } static getIdElem(elem,obj){ if(elem.id) obj[elem.id]=elem; if(elem.children.length===0) return obj; for(let i=0;i<elem.children.length;i++){ Utils.getIdElem(elem.children[i],obj); } } }
以上就是关于原生js实现Js滑块组件的介绍,滑块组件可以实现的效果是很多,大家可以参考上述代码自己来动手实现一下。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
如何调试nodejs程序?下面本篇文章给大家介绍一下nodejs调试debug的方法,希望对大家有所帮助!
这篇文章给大家分享的是有关vue实现dom异步更新的内容,包括Vue异步更新DOM的原理和实例,对大家理解vue dom异步更新有一定的帮助,感兴趣的朋友可以参考。
javascript求pi五次方的方法:1、利用Math对象的“PI”属性获取pi(圆周率)的值;2、使用Math对象的pow()方法计算并返回pi五次方的值,语法“Math.pow(Math.PI,5)”。
这篇文章主要为大家详细介绍了uniapp微信小程序实现一个页面多个倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要给大家介绍了关于在vue3.0中如何友好使用antdv的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008