原生js实现滑块区间组件
导读:收集整理的这篇文章主要介绍了原生js实现滑块区间组件,觉得挺不错的,现在分享给大家,也给大家做个参考。 本文实例为大家分享了js实现滑块区间组件的具体代码,供大家参考,具体内容如下功能需...
收集整理的这篇文章主要介绍了原生js实现滑块区间组件,觉得挺不错的,现在分享给大家,也给大家做个参考。 本文实例为大家分享了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_Xthis.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(alpha0) alpha=0;
let col="rgba(";
for(let i=0;
i3;
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;
ielem.children.length;
i++){
Utils.getIdElem(elem.children[i],obj);
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
您可能感兴趣的文章:- Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
- 基于JS组件实现拖动滑块验证功能(代码分享)
- 基于JavaScript实现拖动滑块效果
- Javascript实现滑块滑动改变值的实现代码
- js实现兼容PC端和移动端滑块拖动选择数字效果
- JS响应鼠标点击实现两个滑块区间拖动效果
- js用拖动滑块来控制图片大小的方法
- 基于Vue.js实现tab滑块效果
- Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
- JS实现网页游戏中滑块响应鼠标点击移动效果
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 原生js实现滑块区间组件
本文地址: https://pptw.com/jishu/594189.html
