gpt4 book ai didi

javascript - 具有绝对位置的 e.pageX

转载 作者:行者123 更新时间:2023-11-28 06:39:24 25 4
gpt4 key购买 nike

我正在使用 this custom JavaScript range slider .我将包装器 (.range-slider) 设置为以下内容:

position:absolute;
left: 60px;

然后,当我拖动 dragger 时,它与光标不在同一位置。 拖动器的 位置有点偏离。

如何让 dragger 跟随光标而不管它的父项在哪里?

我认为相关代码在updateDragger()函数中:

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);
}

JSFiddle

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>

最佳答案

您只需要获取容器元素 #range-slider-1 的位置,即传递给底部 rangeSlider 函数的元素.如果你知道了,你可以从 updateDragger 函数中的 pos 变量中减去位置偏移量。

我添加了 getElemPos 来获取元素的位置。现在您可以将 position left 更改为任何您想要的。

这是一个示例,这仅适用于水平 slider ,不适用于垂直 slider ,但我相信您现在可以轻松地自行解决。 ;)

// 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>

关于javascript - 具有绝对位置的 e.pageX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34404489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com