HTML中有 <input type="range"> 这样的一个控件,但是却只能横向,自己就想着做了一个纵向的。废话不多说,上干货
HTML部分:
<div class="gm-vertical-range" data-gm-value="100" data-gm-max="100" data-gm-min="0">
<div class="gm-vertical-range-slider"></div>
<div class="gm-vertical-range-track"></div>
</div>
CSS部分:
* {
margin: 0;
padding: 0;
}
.gm-vertical-range {
width: 2px;
height: 100px;
border: 1px solid rgb(121, 175, 255);
position: relative;
top: 20px;
left: 20px;
background-color: rgb(15, 147, 255);
border-radius: 1px;
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
} .gm-vertical-range:focus {
outline: none;
}
.gm-vertical-range-slider {
position: relative;
/* 不要让他在边框上 */
top: -3px;
left: -3px;
z-index: 999;
width: 6px;
height: 6px;
border-radius: 100%;;
border: 1px solid rgb(121, 175, 255);
box-shadow: 0 0 10px 2px rgb(121, 175, 255);
background-color: #fff;
cursor: pointer;
}
.gm-vertical-range-track {
width: 100%;
height: 100%;
background-color: rgb(15, 147, 255);
cursor: pointer;
position: relative;
top: -8px;
left: 0;
}
JS部分(我这里是引用了 jquery 的):
// 获取 DOM 元素
var range = $(".gm-vertical-range");
var slider = $(".gm-vertical-range-slider");
var track = $(".gm-vertical-range-track");
// 定义标识符
var isTopBorder = 0;
var isBottomBorder = 0;
var clickPosition = 0;
// 让组件可以获取焦点
range.attr("tabIndex", 1);
// 点击轨道获取焦点并改变值
track.click(function(e) {
range.focus();
slider.css({
top: (-3+e.offsetY) + "px"
});
range.attr("data-gm-value", (100-e.offsetY));
});
// 点击滑块获取焦点
slider.click(function() {
range.focus();
});
// 获取焦点后用上下左右按键改变值
range.keydown(function(e) {
var rangeValue = Number(range.attr("data-gm-value"));
var rangeMax = Number(range.attr("data-gm-max"));
var rangeMin = Number(range.attr("data-gm-min"));
if(e.keyCode === 38 || e.keyCode === 39) {
if(rangeValue < rangeMax) {
slider.css({
top: Number(slider.css("top").split("p")[0]) - 1 + "px"
});
range.attr("data-gm-value", String(rangeValue + 1));
}
}
if(e.keyCode === 37 || e.keyCode === 40) {
if(rangeValue > rangeMin) {
slider.css({
top: Number(slider.css("top").split("p")[0]) + 1 + "px"
});
range.attr("data-gm-value", String(rangeValue - 1));
}
}
});
// 鼠标按下滑块改变可移动状态并获取点击的位置
slider.mousedown(function(event) {
clickPosition = event.clientY - slider[0].offsetTop;
// 给窗口绑定鼠标移动事件
$(document).mousemove(mouseMoveOnWindow);
});
// 松开鼠标按键改变可移动状态
$(document).mouseup(function() {
$(document).unbind("mousemove", mouseMoveOnWindow);
});
// 在窗口上滑动改变值
function mouseMoveOnWindow(event) {
if(isBottomBorder || isTopBorder) {
borderDrage(event);
} else {
trackDrag(event);
}
}
// 在轨道上滑动
function trackDrag(event) {
var currentPosition = event.clientY - clickPosition;
if(currentPosition <= -3) {
changePosition(-3);
isTopBorder = 1;
} else if(currentPosition >= 97) {
changePosition(97);
isBottomBorder = 1;
} else {
changePosition(currentPosition);
}
}
// 在边界上滑动
function borderDrage(event) {
var currentPosition = event.clientY - clickPosition;
if(isTopBorder) {
if(currentPosition > -3) {
changePosition(currentPosition);
isTopBorder = 0;
}
}
if(isBottomBorder) {
if(currentPosition < 97) {
changePosition(currentPosition);
isBottomBorder = 0;
}
}
}
// 改变滑块在轨道中的值
function changePosition(position) {
slider.css({
top: position + "px"
});
range.attr("data-gm-value", (97 - Number(slider.css("top").split("p")[0])));
}
目前只兼容了 Chrome,其他的浏览其后续会测试。弄好兼容性之后可能还会有组件的封装,请期待后续~~