原生js實現滑塊區間元件
阿新 • • 發佈:2021-01-23
本文例項為大家分享了js實現滑塊區間元件的具體程式碼,供大家參考,具體內容如下
功能需求:
1、最小值為0,按照給定的最大值,生成區間範圍;
2、拖動滑塊移動時,顯示相應的範圍區間,滑塊條顯示對應的狀態;
3、點選時,使最近的滑塊移動到滑鼠點選的位置。
預設效果:
當拖動滑塊時,顯示如下:
分析:
- 首先佈局要寫好,一共有4個元素,兩個滑塊和兩個滑塊條。佈局時要考慮到後期對滑塊和滑塊條進行事件監聽,儘可能少地出現事件冒泡;
- 拖動滑塊時,要區分是左邊的滑塊還是右邊的滑塊;
- 滑鼠的click事件和mousedown事件要相容好,這裡統一使用的是mousedown事件;
- 要確定好左右滑塊的最大最小 left 值;
- 滑塊條的顯示就很簡單了,寬度是左、右滑塊的定位差值,left值是左滑塊的left值;
- 因為使用了事件委託機制,而在mousemove和mouseup事件中,無法判斷當前操作的是哪一個滑塊,所以要在滑鼠按下時,將當前操作的物件傳到mousemove事件中;
下面附上程式碼:
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",height:"20px",position:"relative",}) Utils.insertCss(".bgRange",{ width:"240px",height:"3px",backgroundColor:"#dedede",position:"absolute",left:"10px",top:"9px" }) Utils.insertCss(".priceRange",background:"#ffa800",top:"9px" }) Utils.insertCss(".rangeContainer span",{ width: "20px",height: "20px",borderRadius:"50%",border:"1px solid #ccc",background:"#fff",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); } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。