简体   繁体   English

范围滑块-跟​​随拇指的向下箭头

[英]Range Slider - Down Arrow to Follow Thumb

I have a range slider with an output element above it. 我有一个范围滑块,上面有一个输出元素。 Below the output element is a down arrow that follows wherever the thumb is on the slider. 在拇指下方的输出元素下方是一个向下箭头。

I'm using CSS to place the arrow and to animate it as well. 我正在使用CSS放置箭头并对其进行动画处理。

Unfortunately, the arrow is not consistently above the thumb, considering that the slider is responsive. 不幸的是,考虑到滑块是响应性的,箭头并非始终位于拇指上方。

Thanks for your help! 谢谢你的帮助!

 $(function() { var slider = document.getElementById("range-slider"); var output = document.getElementById("range-slider-output"); output.innerHTML = slider.value; slider.oninput = function() { output.innerHTML = this.value; // resets state of user icon $('.fa-user').removeClass("disabled"); if (output.innerHTML == 1) { document.getElementById("range-slider").setAttribute("aria-valuenow", "1"); $('.range-slider-icons li:nth-of-type(2) span, .range-slider-icons li:nth-of-type(3) span, .range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else if (output.innerHTML == 2) { document.getElementById("range-slider").setAttribute("aria-valuenow", "2"); $('.range-slider-icons li:nth-of-type(3) span, .range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else if (output.innerHTML == 3) { document.getElementById("range-slider").setAttribute("aria-valuenow", "3"); $('.range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else { document.getElementById("range-slider").setAttribute("aria-valuenow", "4"); } } }); 
 .range-slider-output { position: relative; display: inline-block; padding: 0.2em 0.75em 0.25em; color: #fff; text-align: center; background: #666; border-radius: 3px; width: 100%; left: calc(50%); flex: 0 0 5%; align-self: center; margin: 0; font-size: 28px; -webkit-transform: translateX(-50%); transform: translateX(-50%); top: -92px; } .range-slider-output::before { position: absolute; top: 50%; left: 0; content: ""; } .range-slider-lg .range-slider-output::before { top: 48px; width: 0; height: 0; border-style: solid; border-width: 12px 12px 0 12px; border-color: #666 transparent transparent transparent; transition: all 0.7s ease-out; } .range-slider-wrap { min-width: 250px; } input[aria-valuenow='1']+.range-slider-output::before { left: 1rem; } input[aria-valuenow='2']+.range-slider-output::before { left: 32.5%; } input[aria-valuenow='3']+.range-slider-output::before { left: 64%; } input[aria-valuenow='4']+.range-slider-output::before { left: 94%; } input[type='range'] { width: 100%; cursor: pointer; padding-top: 90px; } input[type='range'] { -webkit-appearance: none; } input[type='range']::-webkit-slider-runnable-track { width: 100%; height: 5px; background: #e6e5e5; border: 1px solid #999; border-radius: 3px; -webkit-appearance: none; padding: 0 0.5rem; } input[type='range']::-moz-range-track { width: 100%; height: 5px; background: #e6e5e5; border: 1px solid #999; border-radius: 3px; } input[type=range]::-webkit-slider-thumb { width: 28px; height: 28px; margin-top: -11px; background: #999; border: 1px solid #666; border-radius: 50%; -webkit-appearance: none; } input[type='range']::-moz-range-thumb { width: 28px; height: 28px; margin-top: -11px; background: #999; border: 1px solid #666; border-radius: 50%; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="form-group"> <div class="range-slider-wrap range-slider-lg"> <input class="range-slider ng-valid ng-dirty ng-touched" step="1" type="range" id="range-slider" min="1" max="4" data-tooltip-top="true" aria-valuenow="3" aria-valuemin="1" aria-valuemax="4"> <output class="range-slider-output num" id="range-slider-output" for="range-slider"></output> </div> </div> </div> </div> </div> 

The thing is that notches are not simply positionned by percentage like: 关键是,缺口不是简单地按百分比定位,例如:

  • first = 0% 首先= 0%
  • second = 33.3% 秒= 33.3%
  • third = 66.6% 第三= 66.6%
  • fourth = 100% 第四= 100%

The slider-thumb has a dimension... 28px in your case. slider-thumb的尺寸为...在您的情况下为28px。
And there are spacings before the first notch and the last... 并且在第一个刻痕和最后一个刻痕之间有间距...
The arrow also has a width! 箭头也有宽度!

So the alignment calculation can become twisty... 因此对齐计算可能会变得曲折...

I didn't find anything close to a all cases formula . 我没有找到所有案例都接近的公式 But using calc() with a "logical percentage" and an offset in px , it does the job right and is responsive. 但是使用带有“逻辑百分比”px偏移量的calc() ,它可以正确完成工作并且具有响应能力。 It just a matter of a couple try and fail to find the right offset. 只是几次尝试而未能找到正确的偏移量的问题。

Here is the only lines I changed from your snippet: 这是我从您的代码段更改的仅有几行:

input[aria-valuenow='1'] + .range-slider-output::before {
   left: 11px;
}
input[aria-valuenow='2'] + .range-slider-output::before {
   left: calc(33.3% - 4px);
}
input[aria-valuenow='3'] + .range-slider-output::before {
   left: calc(66.6% - 20px);
}
input[aria-valuenow='4'] + .range-slider-output::before {
   left: calc(100% - 36px);
}

I also added bootstrap files (that were in your fiddle). 我还添加了引导文件(在您的小提琴中)。

Updated Fiddle 更新小提琴

Working snippet 工作片段

 $(function() { var slider = document.getElementById("range-slider"); var output = document.getElementById("range-slider-output"); output.innerHTML = slider.value; slider.oninput = function() { output.innerHTML = this.value; // resets state of user icon $('.fa-user').removeClass("disabled"); if (output.innerHTML == 1) { document.getElementById("range-slider").setAttribute("aria-valuenow", "1"); $('.range-slider-icons li:nth-of-type(2) span, .range-slider-icons li:nth-of-type(3) span, .range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else if (output.innerHTML == 2) { document.getElementById("range-slider").setAttribute("aria-valuenow", "2"); $('.range-slider-icons li:nth-of-type(3) span, .range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else if (output.innerHTML == 3) { document.getElementById("range-slider").setAttribute("aria-valuenow", "3"); $('.range-slider-icons li:nth-of-type(4) span').addClass('disabled'); } else { document.getElementById("range-slider").setAttribute("aria-valuenow", "4"); } } }); 
 .range-slider-output { position: relative; display: inline-block; padding: 0.2em 0.75em 0.25em; color: #fff; text-align: center; background: #666; border-radius: 3px; width: 100%; left: calc(50%); flex: 0 0 5%; align-self: center; margin: 0; font-size: 28px; -webkit-transform: translateX(-50%); transform: translateX(-50%); top: -92px; } .range-slider-output::before { position: absolute; top: 50%; left: 0; content: ""; } .range-slider-lg .range-slider-output::before { top: 48px; width: 0; height: 0; border-style: solid; border-width: 12px 12px 0 12px; border-color: #666 transparent transparent transparent; transition: all 0.7s ease-out; } .range-slider-wrap { min-width: 250px; } input[aria-valuenow='1'] + .range-slider-output::before { left: 11px; } input[aria-valuenow='2'] + .range-slider-output::before { left: calc(33.3% - 4px); } input[aria-valuenow='3'] + .range-slider-output::before { left: calc(66.6% - 20px); } input[aria-valuenow='4'] + .range-slider-output::before { left: calc(100% - 36px); } input[type='range'] { width: 100%; cursor: pointer; padding-top: 90px; } input[type='range'] { -webkit-appearance: none; } input[type='range']::-webkit-slider-runnable-track { width: 100%; height: 5px; background: #e6e5e5; border: 1px solid #999; border-radius: 3px; -webkit-appearance: none; padding: 0 0.5rem; } input[type='range']::-moz-range-track { width: 100%; height: 5px; background: #e6e5e5; border: 1px solid #999; border-radius: 3px; } input[type=range]::-webkit-slider-thumb { width: 28px; height: 28px; margin-top: -11px; background: #999; border: 1px solid #666; border-radius: 50%; -webkit-appearance: none; } input[type='range']::-moz-range-thumb { width: 28px; height: 28px; margin-top: -11px; background: #999; border: 1px solid #666; border-radius: 50%; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="form-group"> <div class="range-slider-wrap range-slider-lg"> <input class="range-slider ng-valid ng-dirty ng-touched" step="1" type="range" id="range-slider" min="1" max="4" data-tooltip-top="true" aria-valuenow="3" aria-valuemin="1" aria-valuemax="4"> <output class="range-slider-output num" id="range-slider-output" for="range-slider"></output> </div> </div> </div> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM