Ok, so the problem I'm having is making the output for the range responsive.
It's currently working fine when you run the code because the value is being position in pixels, but when you resize the viewport is doesn't align with the slider thumb correctly. I thought maybe aligning the output using percentages instead of pixels might fix the problem but I'm not sure how to implement it correctly.
I have tried messing around with it but no luck, does anyone know how I can achieve this?
HTML:
<form>
<div class="range-control" data-thumbwidth="20">
<input id="inputRange" type="range" min="0" max="100" step="1" value="0">
<div><output name="rangeVal">0</output></div>
</div>
</form>
CSS:
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-family: Arial, sans-serif;
}
form {
padding-top: 100px;
margin: 0 auto;
}
.range-control {
position: relative;
}
input[type=range] {
display: block;
width: 100%;
margin: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
position: relative;
height: 12px;
border: 1px solid #b2b2b2;
border-radius: 5px;
background-color: #e2e2e2;
box-shadow: inset 0 1px 2px 0 rgba(0,0,0,0.1);
}
input[type=range]::-webkit-slider-thumb {
position: relative;
top: -5px;
width: 20px;
height: 20px;
border: 1px solid #999;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff;
box-shadow: inset 0 -1px 2px 0 rgba(0,0,0,0.25);
border-radius: 100%;
cursor: pointer;
}
output {
position: absolute;
top: 20px;
width: 50px;
height: 24px;
border: 1px solid #e2e2e2;
margin-left: -15px;
background-color: #fff;
border-radius: 3px;
color: #777;
font-size: .8em;
line-height: 24px;
text-align: center;
}
input[type=range]:active + output {
display: block;
}
JQUERY:
$('.range-control').each(function(){
var container = $(this),
input = container.find('input'),
output = container.find('output'),
rangeWidth = input.width(),
thumbWidth = container.attr('data-thumbwidth'),
startValue = input.val(),
startOffset = ((rangeWidth - thumbWidth) / 100) * startValue + '%';
output
.css({
'left' : startOffset
});
$(input).on('input', function(){
var value = this.value,
offset = ((rangeWidth - thumbWidth) / 100) * value;
output
.val(value)
.css({
'left' : offset
});
});
});
JSFiddle
Any help would be appreciated greatly!!!
** EDIT ** Please Read
So below Mohamed-Yousef answered the question in the way he would do it which does work, so I have up voted it, however he has duplicated the variables twice in the code (see his answer for details about this). I think there is a more efficient way of doing this (using less code), so if anyone has a better way of doing this please share.
simply you need to update your variable on window resize to change its values .. and make your input event inside each function print it more than one time and that make it not available to read a new variable after resize .. so I take it out and run each event individual
AFTER EDIT
$(document).ready(function(){
var container,input,output,rangeWidth,thumbWidth,startValue,startOffset;
// make a function to update variable
var update_variable = function(){
$('.range-control').each(function(){
container = $(this);
input = container.find('input');
output = container.find('output');
rangeWidth = input.width();
thumbWidth = container.attr('data-thumbwidth');
startValue = input.val();
startOffset = ((rangeWidth - thumbWidth) / 100) * startValue;
output
.css({
'left' : startOffset
});
});
}
// update variable after document ready
update_variable();
// input input event
$('.range-control > input').on('input', function(){
var value = this.value,
offset = ((rangeWidth - thumbWidth) / 100) * value;
$(this).closest('.range-control').find('output')
.val(value +'%')
.css({
'left' : offset
});
});
// update variable in window resize
$(window).on('resize',update_variable);
});
DEMO HERE
Important Note: this code will work perfect if you have inputs with the same width .. if its not the same width you need to use an array of elements to get each element width
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With