【发布时间】:2011-03-09 03:46:29
【问题描述】:
我正在用 JavaScript 制作拖放引擎,但我不知道如何设置 dragObj 的正确位置,因为它会根据父元素的定位类型而变化(dragObj 是否也会根据其父元素的“父元素”等?)。
所以,我的 dragObj 看起来像这样:
function makeObj(event) {
var obj = new Object();
var e = event.target;
obj.element = e;
obj.boundElement = null;
while(e = e.parentNode) {
if(~e.className.search(/bound/)) { //if(/bound/.test(e.className)) {
obj.boundElement = e;
break;
}
}
if(obj.boundElement == null)
obj.boundElement = document.body;
// I would like to find the correct minimum bounds with findPos(); however, I need
// findPos() to work with every type of positioning (absolute, relatice, ect.)
//var elemPos = findPos(obj.boundElement);
//obj.minBoundX = elemPos.x;
//obj.minBoundY = elemPos.y;
obj.minBoundX = obj.boundElement.offsetLeft + obj.boundElement.offsetWidth - obj.element.offsetWidth;
obj.minBoundY = obj.boundElement.offsetTop + obj.boundElement.offsetHeight - obj.element.offsetHeight;
obj.maxBoundX = obj.boundElement.offsetLeft;
obj.maxBoundY = obj.boundElement.offsetTop;
setHelperBoxPos(obj);
obj.posX = event.clientX - obj.element.offsetLeft;
obj.posY = event.clientY - obj.element.offsetTop;
return obj;
}
所以,当我制作一个 dragObj 时,我还设置了它的“位置”和它的bounding element。在我设置 .minBoundX 和 .minBoundY 属性之前的评论部分中,我解释了我想如何设置它们;但是,它不起作用,因为 findPos() 函数不起作用。
这里是 findPos() 函数:
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 };
}
}
如果bounding element 设置了position: absolute;,我相信此功能有效,但我希望用户能够设置其定位类型。另外,bounding element 由.bound 类设置,dragObj 由.drag 类设置。
这是 HTML:
<div id="min" class="helper-box" style="border: 1px solid blue;"></div>
<div id="max" class="helper-box" style="border: 1px solid red;"></div>
<div id="center">
<h1>Hello World! <hr /></h1>
<div id="box" class="bound">
<p class="drag square"> One </p>
<p class="drag square"> Two </p>
</div>
</div>
这是 CSS:
@charset "utf-8";
/* CSS Document */
* {
padding: 0px;
margin: 0px;
}
body {
background-color:#DFDFDF;
}
.drag {
position: absolute;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.bound {
;
}
.square {
width: 100px;
height: 100px;
background: #1047A9;
cursor:move;
border-radius: 25px;
-moz-border-radius: 25px;
}
#center {
width: 500px;
margin: auto;
margin-top: 50px;
background-color: #29477F;
color: #E8E8E8;
text-align: center;
border-radius: 25px;
-moz-border-radius: 25px;
}
#box {
background-color: #009EBE;
height: 275px;
border-radius: 0 0 25px 25px;
-moz-border-radius: 0 0 25px 25px;
opacity: 1.0;
}
.helper-box {
position: absolute;
width: 5px;
height: 5px;
}
这是整个引擎:
// JavaScript Document
var dragObj;
document.addEventListener("mousedown", down, false);
function down(event) {
if(~event.target.className.search(/drag/)) {
dragObj = makeObj(event);
dragObj.element.style.zIndex="100";
document.addEventListener("mousemove", freeMovement, false);
}
}
function freeMovement(event) {
if (typeof(dragObj.element.mouseup) == "undefined")
document.addEventListener("mouseup", drop, false);
//Prevents redundantly adding the same event handler repeatedly
dragObj.element.style.left = Math.max(dragObj.maxBoundX, Math.min(dragObj.minBoundX, event.clientX - dragObj.posX)) + "px";
dragObj.element.style.top = Math.max(dragObj.maxBoundY, Math.min(dragObj.minBoundY, event.clientY - dragObj.posY)) + "px";
}
function drop() {
dragObj.element.style.zIndex="1";
document.removeEventListener("mousemove", freeMovement, false);
document.removeEventListener("mouseup", drop, false);
//alert("DEBUG_DROP");
}
function makeObj(event) {
var obj = new Object();
var e = event.target;
obj.element = e;
obj.boundElement = null;
while(e = e.parentNode) {
if(~e.className.search(/bound/)) { //if(/bound/.test(e.className)) {
obj.boundElement = e;
break;
}
}
if(obj.boundElement == null)
obj.boundElement = document.body;
// I would like to find the correct minimum bounds with findPos(); however, I need
// findPos() to work with every type of positioning (absolute, relatice, ect.)
//var elemPos = findPos(obj.boundElement);
//obj.minBoundX = elemPos.x;
//obj.minBoundY = elemPos.y;
obj.minBoundX = obj.boundElement.offsetLeft + obj.boundElement.offsetWidth - obj.element.offsetWidth;
obj.minBoundY = obj.boundElement.offsetTop + obj.boundElement.offsetHeight - obj.element.offsetHeight;
obj.maxBoundX = obj.boundElement.offsetLeft;
obj.maxBoundY = obj.boundElement.offsetTop;
setHelperBoxPos(obj);
obj.posX = event.clientX - obj.element.offsetLeft;
obj.posY = event.clientY - obj.element.offsetTop;
return obj;
}
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 };
}
}
function setHelperBoxPos(obj) {
var minBox = document.getElementById('min');
minBox.style.left = obj.minBoundX + 'px';
minBox.style.top = obj.minBoundY + 'px';
var maxBox = document.getElementById('max');
maxBox.style.left = obj.maxBoundX + 'px';
maxBox.style.top = obj.maxBoundY + 'px';
}
为了您的方便,我还做了一个 jsfiddle:http://jsfiddle.net/2XGhK/
那么,我如何创建一个允许不同类型定位的 findPos() 函数。我是否需要创建另一个 findPos() 函数以允许 dragObj 也可以进行任何类型的定位?
重要请不要推荐使用库(除非您建议查看它以获取有关它们如何处理定位的提示)。原因是我只是在学习语言并且构建东西对我有帮助这样做。在我理解语言之前学习图书馆有什么意义?
最重要的是,我非常感谢您的所有帮助。谢谢。
【问题讨论】:
标签: javascript html css drag-and-drop