使用layui框架 滑块组件 slider 时遇到的问题,以下图为例,我创建了一个总滑块和3个滑块,改变总滑块可以控制滑块123:
1、我的需求是加上标尺,layui没有该功能,自己写了一个简单的,代码在下面。
2、移动端不支持滑动,只能点击,解决修改了源码。
3、设置滑块值,得到实例对象可以通过以下代码设置值,但是我动态创建的slider要怎么用变量接,难道定义多个变量吗,最后我是把渲染的滑块实例对象放到了数组中。
- var inst = slider.render(options);
- console.log(inst); // 得到当前实例对象
- inst.setValue(value, index)
4、我在点击总滑块时会给滑块123同时赋值改变,但是再点击某个分滑块的上下箭头时,滑块值不对,会根据上次的值修改。
html:
<ul id="avVolumAll">
<li>
<div class="layui-form-item"><span>滑块总控制</span></div>
<div class="layui-form-item vo-slider-div">
<div class="layui-inline fl" id="avAllVolumSlider"></div>
<div class="fl volum-rule">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="fl volum-rule-num">
<ul>
<li><span>100</span></li>
<li><span>80</span></li>
<li><span>60</span></li>
<li><span>40</span></li>
<li><span>20</span></li>
<li><span>0</span></li>
</ul>
</div>
</div>
<div><i id="avAllVolumeIcon" class="iconfont icon-24gl-volumeHigh" onclick="avVolumeMuteBtn(999, this)"></i></div></li>
</ul>
<ul id="avVolumUl">
</ul>
css:
.fl {
float: left;
}
#avVolumAll, #avVolumUl {
li {
float: left;
width: 100px;
text-align: center;
color: #fff;
border: 1px outset #335e77;
padding: 18px 14px;
margin: 10px;
box-sizing: border-box;
font-size: 13px;
.vo-slider-div {
margin-top: 66px;
.layui-slider-wrap-btn {
border-radius: 2px;
}
.layui-slider-vertical {
margin-left: 14px;
}
}
.iconfont {
font-size:22px;
}
}
.volum-rule {
width: 15px;
height: 200px;
ul li{
border: 0;
padding: 0;
margin: 0;
width: 12px;
height: 40px;
border-bottom: 1px solid #838080;
// border-left: 1px solid #838080;
&:first-child{
border-top: 1px solid #838080;
}
}
}
.volum-rule-num {
width: 18px;
height: 200px;
ul li{
border: 0;
margin: 0;
width: 18px;
padding: 0;
height: 40px;
position: relative;
span {
font-size: 12px;
position: absolute;
left: 2px;
top: -7px;
}
}
}
}
js:
//初始化总控制滑块
let audioAllVolSlide = slider.render({
elem: '#avAllVolumSlider',
value: 50,
min: 0,
max: 100,
input: true ,
type: 'vertical', // 垂直滑块
height : 200,
change: function (value) {
console.log("全部== " + value); //动态获取滑块数值
let val = parseInt(value);
if(audioVolSlideArr.length > 0) {
for(let j = 0;j< audioVolSlideArr.length;j++) {
audioVolSlideArr[j].setValue(val);
}
}
if(value == 0) {
$("#avAllVolumeIcon").attr("class","iconfont icon-24gl-volumeCross");
} else {
$("#avAllVolumeIcon").attr("class","iconfont icon-24gl-volumeHigh");
}
}
});
let audioVolSlideArr = [];//所有小滑块数组
let list = [{ "volumeL": 14, "name": "滑块1" }, { "volumeL": 50, "name": "滑块2" }, { "volumeL": 40, "name": "滑块3" }];//模拟数据
function displayAvVolumUl() {
$("#avVolumUl").empty();
audioVolSlideArr.length = 0;
for (let i = 0; i < list.length; i++) {
let item = list[i];
let vClass = item.volumeL == 0 ? "iconfont icon-24gl-volumeCross" : "iconfont icon-24gl-volumeHigh";
let html = `<li>
<div class="layui-form-item"><span>${item.name}</span></div>
<div class="layui-form-item vo-slider-div">
<div class="layui-inline fl" id="avVolumSlider-${i}"></div>
<div class="fl volum-rule">
<ul><li></li><li></li><li></li><li></li><li></li></ul>
</div>
<div class="fl volum-rule-num">
<ul><li><span>100</span></li><li><span>80</span></li><li><span>60</span></li><li><span>40</span></li><li><span>20</span></li><li><span>0</span></li></ul>
</div>
</div>
<div><i id="avVolumeIcon-${i}" class="${vClass}" onclick="avVolumeMuteBtn(${i}, this)"></i></div></li>`;
$("#avVolumUl").append(html);
let sliderItem = slider.render({
elem: '#avVolumSlider-' + i,
value: item.volumeL,
min: 0,
max: 100,
input: true, // 输入框
type: 'vertical', // 垂直滑块
height: 200,
change: function (value) {
if (value == 0) {
$("#avVolumeIcon-" + i).attr("class", "iconfont icon-24gl-volumeCross");
} else {
$("#avVolumeIcon-" + i).attr("class", "iconfont icon-24gl-volumeHigh");
}
}
});
audioVolSlideArr.push(sliderItem);
}
}
兼容移动端拖拽滑块滑动,我在mousedown下面加了touchstart 这一段代码,暂时解决
//滑块滑动
sliderAct.find('.' + SLIDER_WRAP_BTN).each(function(index){
var othis = $(this);
othis.on('mousedown', function(e){
e = e || window.event;
var oldleft = othis.parent()[0].offsetLeft
,oldx = e.clientX;
if(options.type === 'vertical'){
oldleft = sliderWidth() - othis.parent()[0].offsetTop - sliderWrap.height()
oldx = e.clientY;
};
var move = function(e){
e = e || window.event;
var left = oldleft + (options.type === 'vertical' ? (oldx - e.clientY) : (e.clientX - oldx));
if(left < 0)left = 0;
if(left > sliderWidth())left = sliderWidth();
var reaLeft = left / sliderWidth() * 100 / step;
change(reaLeft, index);
othis.addClass(ELEM_HOVER);
sliderAct.find('.' + SLIDER_TIPS).show();
e.preventDefault();
};
var up = function(){
othis.removeClass(ELEM_HOVER);
sliderAct.find('.' + SLIDER_TIPS).hide();
};
createMoveElem(move, up)
});
//20230706 兼容移动端滑动
othis.on('touchstart', function(e){
console.log(e)
e = e || window.event;
var oldleft = othis.parent()[0].offsetLeft
,oldx = e.originalEvent.changedTouches[0].clientX;
if(options.type === 'vertical'){
oldleft = sliderWidth() - othis.parent()[0].offsetTop - sliderWrap.height()
oldx = e.originalEvent.changedTouches[0].clientY;
};
othis.on('touchmove', function(e){
console.log("move=== ");
e = e || window.event;//e.originalEvent.changedTouches[0]
var left = oldleft + (options.type === 'vertical' ? (oldx - e.originalEvent.changedTouches[0].clientY) : (e.originalEvent.changedTouches[0].clientX - oldx));
if(left < 0)left = 0;
if(left > sliderWidth())left = sliderWidth();
var reaLeft = left / sliderWidth() * 100 / step;
change(reaLeft, index);
othis.addClass(ELEM_HOVER);
sliderAct.find('.' + SLIDER_TIPS).show();
e.preventDefault();
});
othis.on('touchend', function(e){
// elemMove.remove();
sliderAct.find('.' + SLIDER_TIPS).hide();
});
});
});
点击总控制单个滑块后,点击单个的上下箭头值不对,加上 inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(); 暂时解决
//点击加减输入框
sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){
$(this).on('click', function(){
inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();//20230707 setValue后不对,inputValue记录的上次滑块的数,重新获取一下
if(index == 1){
inputValue = inputValue - options.step < options.min
? options.min
: Number(inputValue) - options.step;
}else{
inputValue = Number(inputValue) + options.step > options.max
? options.max
: Number(inputValue) + options.step;
};
var inputScale = (inputValue - options.min) / (options.max - options.min) * 100 / step;
change(inputScale, 0);
});
});