我正在尝试用 JavaScript 制作一个拖放引擎。现在,我添加了一个边界功能,它将把 .drag
对象捕获在其父元素内。然而,要做到这一点,我需要了解定位在 html 中是如何工作的,但我没有。谁能详细解释一下吗?
Javascript 引擎:
// JavaScript Document
var posX;
var posY;
var element;
var currentPos;
document.addEventListener("mousedown", drag, false);
function drag(event) {
if(~event.target.className.search(/drag/)) {
element = event.target;
element.style.zIndex="100";
currentPos = findPos(element);
posX = event.clientX -currentPos.x;
posY = event.clientY -currentPos.y;
if(~event.target.className.search(/bound/))
document.addEventListener("mousemove", boundMovement, false);
else
document.addEventListener("mousemove", freeMovement, false);
}
}
function freeMovement(event) { // This functions works
if (typeof(element.mouseup) == "undefined")
document.addEventListener("mouseup", drop, false);
//Prevents redundantly adding the same event handler repeatedly
element.style.left = event.clientX - posX + "px";
element.style.top = event.clientY - posY + "px";
}
function boundMovement(event) { // This function doesn't work
if (typeof(element.mouseup) == "undefined")
document.addEventListener("mouseup", drop, false);
//Prevents redundantly adding the same event handler repeatedly
// Below logic is false- I wish to understand why =]
currentPos = findPos(element.offsetParent);
if((event.clientX - posX) <= currentPos.x)
element.style.left = event.clientX - posX + "px";
if((event.clientY - posY) <= currentPos.y)
element.style.top = event.clientY - posY + "px";
}
function drop() {
element.style.zIndex="1";
document.removeEventListener("mousemove", boundMovement, false);
document.removeEventListener("mousemove", freeMovement, false);
document.removeEventListener("mouseup", drop, false);
//alert("DEBUG_DROP");
}
function findPos(obj) { // Donated by `lwburk` on StackOverflow
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
}
这是我正在使用的 CSS:
@charset "utf-8";
/* CSS Document */
.drag {
position: absolute;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.bound {
/* Class to signify that the drag_object can not leave the parent element */
;
}
.square {
width: 100px;
height: 100px;
background: red;
cursor:move;
}
p {
padding: 0px;
margin: 0px;
outline-style: dotted;
outline-color: #000;
outline-width: 1px;
}
一些 HTML 示例:
<p class="drag bound square">Thing One</p>
<p class="drag square">Thing Two</p>
请注意,我包含了 JavaScript,以便如果我对如何相对于我所编写的内容应用事物有疑问。另外,感谢大家的阅读和帮助。 StackOverflow 是学习如何使用 JavaScript 编码的绝佳资源。
编辑:
1) 我应该说我正在编写引擎来帮助我学习该语言。这是我学习 JavaScript 的第一周,我希望在使用库之前能够使用该语言进行编码。
2)例如,我真的希望有人解释一下偏移量在这里是如何工作的。我想知道如何不使用 position:absolute
来制作我的 JavaScript 引擎,而是使用 position:relative
以便元素可以堆叠在彼此之上等。
最佳答案
我已在 http://jsfiddle.net/vJ6r6/ 发布了解决方案.
首先,我将要拖动的元素嵌套在边界框内:
<div class="bound">Thing One
<div class="drag square">Thing Two</div>
<div class="drag square">Thing Three</div>
</div>
此外,我将它们变成了 div,因为 p 不能嵌套。 (不要忘记也更改样式声明。)
然后,我在边界框上设置样式:
<style>
.bound {
margin: 100px;
width: 400px;
height: 400px;
position: relative;
}
</style>
关键属性是position:relative
,这会导致其中的元素相对于它定位,而不是相对于页面定位。 请注意,因为我使用的是相对定位,所以当您想要将元素保留在特定容器中时,此示例效果最佳。
我对 JavaScript 的更改更为彻底,所以这就是整个事情:
<script>
var dragInfo;
function down(event) {
if (~event.target.className.search(/drag/)) {
document.addEventListener("mouseup", drop, false);
var t = event.target;
t.style.zIndex = 100;
dragInfo = {
element: t,
// record the bounds
maxX: t.parentNode.offsetWidth - t.offsetWidth,
maxY: t.parentNode.offsetHeight - t.offsetHeight,
// we don't need findPos, because it's no longer relative to the page
posX: event.clientX - t.offsetLeft,
posY: event.clientY - t.offsetTop
};
document.addEventListener("mousemove", freeMovement, false);
}
}
function freeMovement(event) {
// the min and max calculations keep the X and Y within the bounds
dragInfo.element.style.left = Math.max(0, Math.min(event.clientX - dragInfo.posX, dragInfo.maxX)) + "px";
dragInfo.element.style.top = Math.max(0, Math.min(event.clientY - dragInfo.posY, dragInfo.maxY)) + "px";
}
function drop() {
dragInfo.element.style.zIndex = 1;
document.removeEventListener("mousemove", freeMovement, false);
document.removeEventListener("mouseup", drop, false);
}
document.addEventListener("mousedown", down, false);
</script>
请注意这一行:
dragInfo.element.style.left = Math.max(0, Math.min(event.clientX - dragInfo.posX, dragInfo.maxX)) + 'px';
相当于:
var x = event.clientX - dragInfo.posX;
if (x < 0) x = 0;
if (x > dragInfo.maxX) x = dragInfo.maxX;
dragInfo.element.style.left = x + 'px';
关于javascript - HTML/CSS 中的定位是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5125023/