我正在使用this custom JavaScript range slider。我将包装器(position:absolute;
left: 60px;
)设置为以下内容:
dragger
然后,当我拖动dragger's
时,它与光标的位置不同。 dragger
位置有点偏离。
我怎样才能让updateDragger() function
跟随光标,无论父母在哪里?
我认为相关代码位于e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
config.drag(cachePosition);
}
:
function rangeSlider(elem, config) {
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
var defaults = {
value: 0, // set default value on initiation from `0` to `100` (percentage based)
vertical: false, // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ } // function to return the range slider value into something
};
for (var i in defaults) {
if (typeof config[i] == "undefined") config[i] = defaults[i];
}
function addEventTo(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
var isVertical = config.vertical;
elem.className = (elem.className + ' range-slider ' + (isVertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
function updateDragger(e) {
e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
config.drag(cachePosition);
}
}
function initDragger() {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
config.drag(config.value);
}
range.appendChild(dragger);
elem.appendChild(range);
initDragger();
}
rangeSlider(document.getElementById('range-slider-1'), {
value: 30,
drag: function(v) {
document.getElementById('result-area').innerHTML = v + '%';
}
});
.range-slider {
width: 50%;
position: absolute;
top: 50px;
left: 60px;
}
.range-slider-track {
width: auto;
height: 20px;
margin: 0 auto;
position: relative;
}
.range-slider-track:before {
content: "";
display: block;
position: absolute;
top: 9px;
left: 0;
width: 100%;
height: 2px;
background-color: black;
}
.range-slider-track .dragger {
display: block;
width: 10px;
height: inherit;
position: relative;
z-index: 2;
background-color: red;
cursor: inherit;
/* opacity:.6; */
}
.range-slider-vertical {
display: inline-block;
vertical-align: middle;
margin: 0 1em 1em 0;
}
.range-slider-vertical .range-slider-track {
cursor: n-resize;
width: 20px;
height: 100px;
}
.range-slider-vertical .range-slider-track:before {
top: 0;
right: auto;
left: 9px;
width: 2px;
height: 100%;
}
.range-slider-vertical .range-slider-track .dragger {
width: inherit;
height: 10px;
}
.no-select {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<div id="range-slider-1"></div>
<p id="result-area"></p>
{{1}}
答案 0 :(得分:0)
问题出在你的css代码中。
left
属性/值正在抛弃dragger
元素。的 See here 即可。删除后,拖动器将按预期运行。
也许这是一个错误,我会report it to the repo(似乎你已经拥有)并避免使用position: absolute
和left
或right
属性直到解决。
答案 1 :(得分:0)
您只需要获取容器元素#range-slider-1
的位置,即传递给底部rangeSlider
函数的元素。如果你有,你可以从pos
函数中的updateDragger
变量中减去位置偏移量。
我已添加getElemPos
以获取元素位置。
现在,您可以将position
left
更改为您想要的内容。
这是一个例子,这只适用于水平滑块而不适用于垂直滑块,但我相信你现在可以轻松地自己解决这个问题了。 ;)
// This will help to get an elements position.
function getElemPos (elem) {
var xPos = 0,
yPos = 0;
while (elem) {
xPos += (elem.offsetLeft - elem.scrollLeft + elem.clientLeft);
yPos += (elem.offsetTop - elem.scrollTop + elem.clientTop);
elem = elem.offsetParent;
}
return { x: xPos, y: yPos };
}
function rangeSlider(elem, config) {
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
var defaults = {
value: 0, // set default value on initiation from `0` to `100` (percentage based)
vertical: false, // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ } // function to return the range slider value into something
};
for (var i in defaults) {
if (typeof config[i] == "undefined") config[i] = defaults[i];
}
function addEventTo(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
var isVertical = config.vertical;
elem.className = (elem.className + ' range-slider ' + (isVertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
var elemXY = getElemPos(elem);
function updateDragger(e) {
e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? (e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft) : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
// Here you can substract the #range-slider-1 x postion from the mouse position.
pos -= elemXY.x;
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
config.drag(cachePosition);
}
}
function initDragger() {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
config.drag(config.value);
}
range.appendChild(dragger);
elem.appendChild(range);
initDragger();
}
rangeSlider(document.getElementById('range-slider-1'), {
value: 30,
drag: function(v) {
document.getElementById('result-area').innerHTML = v + '%';
}
});
.range-slider {
width: 50%;
position: absolute;
top: 50px;
left: 25%;
}
.range-slider-track {
width: auto;
height: 20px;
margin: 0 auto;
position: relative;
cursor: pointer;
}
.range-slider-track:before {
content: "";
display: block;
position: absolute;
top: 9px;
left: 0;
width: 100%;
height: 2px;
background-color: black;
}
.range-slider-track .dragger {
display: block;
width: 10px;
height: inherit;
position: relative;
z-index: 2;
background-color: red;
cursor: inherit;
/* opacity:.6; */
}
.range-slider-vertical {
display: inline-block;
vertical-align: middle;
margin: 0 1em 1em 0;
}
.range-slider-vertical .range-slider-track {
cursor: n-resize;
width: 20px;
height: 100px;
}
.range-slider-vertical .range-slider-track:before {
top: 0;
right: auto;
left: 9px;
width: 2px;
height: 100%;
}
.range-slider-vertical .range-slider-track .dragger {
width: inherit;
height: 10px;
}
.no-select {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<div id="range-slider-1"></div>
<p id="result-area"></p>