I am currently trying to make some range sliders with boxes over them, that show the current value of the sliders. Since all the ways in the internet didn't work I just tried to move a box with the slider thumber. But when my window is smaller, then the boxes aren't at the right place and when I resize the window they move around. Does anyone has an idea about how I can put them at the right position, even if the window is smaller or resized ??
Here is my code (This is just for testing and definitely not perfect or final) :
<html>
<head>
<title>Home</title>
<!-- CSS -->
<link rel="stylesheet" href="stylesheet.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div id="login-box">
<div id="logo"><img border="0" src="logo.png"></div>
<div id="text_boost">Boost your account now!</div>
<div id="slider1"><input id="range1" type="range" min="10" max="100" value="0" step="1" onchange="change(1)"></div>
<div id="slider2"><input id="range2" type="range" min="0.5" max="4" value="0" step="0.5" onchange="change(2)"/></div>
</div>
<div id="sliderInfo1" class= "ui-widget-content" style="background-color: #d9d9d9; border-radius:10px; width: 59px;
height: 22px; text-align:center; display: table">
<span style="line-height: 22px"></span>
<div style="display: table-cell; vertical-align: middle; text-align: center; font-size:12px;"><span id="slider_1">10.000</span></div>
</div>
<div id="sliderInfo2" class= "ui-widget-content" style="background-color: #d9d9d9; border-radius:10px; width: 59px;
height: 22px; text-align:center; display: table">
<span style="line-height: 22px"></span>
<div style="display: table-cell; vertical-align: middle; text-align: center; font-size:12px;"><span id="slider_2">500</span></div>
</div>
<script type="text/javascript">
var newPoint, newPlace, offset;
var savedOffset_1 = document.getElementById("sliderInfo1").getBoundingClientRect().top -
document.getElementById("range1").getBoundingClientRect().top;
change(1);
var savedOffset_2 = document.getElementById("sliderInfo2").getBoundingClientRect().top -
document.getElementById("range2").getBoundingClientRect().top;
change(2);
function change (id) {
var el = $("#range" + id);
var top = el.position().top;
var left = el.position().left;
var bodyRect = document.getElementById("range" + id).getBoundingClientRect(),
elemRect = document.getElementById("sliderInfo" + id).getBoundingClientRect(),
offset_2 = elemRect.left - bodyRect.left;
if(id == 1) {
offset_1 = savedOffset_1;
} else if(id == 2) {
offset_1 = savedOffset_2;
}
// Measure width of range input
var width = 430;
// Figure out placement percentage between left and right of input
newPoint = (el.val() - el.attr("min")) / (el.attr("max") - el.attr("min"));
offset = -1;
// calculate new box place
if (newPoint < 0) {
newPlace = 0;
} else if (newPoint > 1) {
newPlace = (bodyRect.left - width);
} else {
newPlace = width * newPoint + left + width + (59 / 2);
offset -= newPoint;
}
// move box
$("#sliderInfo" + id).css({ position: "fixed", left: newPlace, marginLeft: offset + "%", top: top - offset_1 - 5 + "px",
width: 59 + "px", height: 22 + "px", display: "table", fontSize: 12 + "px",
backgroundColor: "#d9d9d9", borderRadius: 10 + "px", verticalAlign: "middle", textAlign: "center",
lineHeight: 22 + "px"})
.text(numberWithCommas(el.val() * 1000));
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}
</script>
</body>
My CSS: http://pastebin.com/rASpFWjN
By positioning them as fixed you will also have to capture the window.onresize
and window.onscroll
events, and position your labels accordingly. This is because position: fixed
will always be relative to your browsers viewport. So an element with position: fixed; top: 100px; left: 100px
will always be 100px from the top left corner of your window, regardless of how big the window is or how much it has scrolled.
In your case however, using position: fixed
will make the code unnecessarily complicated. You can just position the labels inside the slider divs, so they will always be relative to the sliders.
<div id="slider1">
<div id="sliderInfo1" class="sliderInfo">
<span id="slider_1">10.000</span>
</div>
<input id="range1" type="range" min="10" max="100" value="0" step="1" />
</div>
<div id="slider2">
<div id="sliderInfo2" class="sliderInfo">
<span id="slider_2">500</span>
</div>
<input id="range2" type="range" min="0.5" max="4" value="0" step="0.5" />
</div>
This also means you'll have to do less position calculations in javascript.
function change(id) {
var thumbWidth = 28;
var el = $("#range" + id);
var inputWidth = el.width() - thumbWidth;
var newPoint = (el.val() - el.attr("min")) / (el.attr("max") - el.attr("min"));
var newPlace = inputWidth * newPoint;
// add half the thumb width to the new left to position correctly.
newPlace += (thumbWidth / 2);
$("#sliderInfo" + id).css({
left: newPlace,
}).text(numberWithCommas(el.val() * 1000));
}
A full example of this on https://jsfiddle.net/dnm7qr6j/