滑块组件就是一个允许用户在有限区间内通过移动滑块来选择值的组件。滑块组件的应用是比较常见的,例如商品价格区间筛选,音量设置,滑块验证等等。这篇文章就给大家介绍一下用原生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进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
长按识别二维码并关注微信
更方便到期提醒、手机管理