【发布时间】:2011-07-05 02:05:39
【问题描述】:
我正在制作一个拖放式 JavaScript 引擎。我学习了如何将边界框设置为父元素。但是,现在我希望将边界框设置为任何父级的任何父级,或者设置为整个页面(无边界)。
现在我的 Javascript 引擎看起来像:
// JavaScript Document
var dragObj;
document.addEventListener("mousedown", down, false);
function down(event) {
if(~event.target.className.search(/drag/)) {
dragObj = makeObj(event.target);
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(0, Math.min(event.clientX - dragObj.posX, dragObj.boundX)) + "px";
dragObj.element.style.top = Math.max(0, Math.min(event.clientY - dragObj.posY, dragObj.boundY)) + "px";
}
function drop() {
dragObj.element.style.zIndex="1";
document.removeEventListener("mousemove", freeMovement, false);
document.removeEventListener("mouseup", drop, false);
//alert("DEBUG_DROP");
}
function makeBoundlessObj(e) {
var obj = new Object();
obj.element = e;
obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;
obj.posX = event.clientX - e.offsetLeft;
obj.posY = event.clientY - e.offsetTop;
return obj;
}
function makeObj(e) {
obj = new Object();
obj.element = e;
obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;
obj.posX = event.clientX - e.offsetLeft;
obj.posY = event.clientY - e.offsetTop;
var curleft = curtop = 0;
if (e.offsetParent) {
do {
curleft += e.offsetLeft;
curtop += e.offsetTop;
//alert(e.id + ":" + e.innerHTML);
if(~e.className.search(/bound/)) {
obj.boundX = curleft - obj.element.offsetLeft;
obj.boundY = curtop - obj.element.offsetTop;
return obj;
}
} while (e = e.offsetParent);
}
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 };
}
}
我的 CSS 如下:
@charset "utf-8";
/* CSS Document */
* {
padding: 0px;
margin: 0px;
}
.drag {
position: absolute;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.bound {
position: relative;
}
.square {
width: 100px;
height: 100px;
background: red;
cursor:move;
}
#center {
width: 500px;
height: 300px;
margin: auto;
margin-top: 50px;
background-color:#ccc;
text-align: center;
border-radius: 25px;
-moz-border-radius: 25px;
}
#box {
background-color: #FF3;
height: 278px;
border-radius: 0 0 25px 25px;
-moz-border-radius: 0 0 25px 25px;
opacity: 0.5;
}
而且我的 HTML 非常干净:
<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>
我已经多次尝试制作正确的功能。我会给出一个我做的不起作用的,我会列出原因:
如果没有bounds,我将默认bounds设置为父元素(因为我不知道如何设置bounds为整个页面)
如果其中一个父元素 IS 绑定,那么我没有正确设置绑定坐标(同样,我不知道如何)
哦,我在创建 drag_object 时设置了边界。
JavaScript 创建函数:
function makeObj(e) {
var obj = new Object();
obj.element = e;
obj.boundX = e.parentNode.offsetWidth - e.offsetWidth;
obj.boundY = e.parentNode.offsetHeight - e.offsetHeight;
obj.posX = event.clientX - e.offsetLeft;
obj.posY = event.clientY - e.offsetTop;
var curleft = curtop = 0;
if (e.offsetParent) {
do {
curleft += e.offsetLeft;
curtop += e.offsetTop;
//alert(e.id + ":" + e.innerHTML);
if(~e.className.search(/bound/)) {
obj.boundX = curleft - obj.element.offsetLeft;
obj.boundY = curtop - obj.element.offsetTop;
return obj;
}
} while (e = e.offsetParent);
}
return obj;
}
设置边界框的正确数学是什么?为什么?我可以摆脱.bound 类中的position: relative 吗?我可以让.drag 类不是position: absolute 吗?我知道所有这些事情可能会极大地影响边界函数的编写方式。如果我不得不在 .drag 类或 .bound 类不需要特定类型的 position 之间进行选择,我会选择将 .bound 类设置为任何类型定位。
感谢大家的阅读和帮助!它对我意义重大;我是一名全日制(寄宿)高中生,空闲时间很少=/
编辑:
我应该注意到我在学习 Javascript 的第十天或第十五个小时,这取决于你如何看待它,我想在开始使用像 jQuery 这样的库之前学习这门语言。这个引擎是我为了知识和学习语言而为自己做的一个学术练习=]
【问题讨论】:
-
+1 - 绝对值得自己学习 JavaScript 而不是依赖库。但是,您可能可以从解构 jQuery UI 可拖动库的源代码中学到很多东西(我知道它专门支持将任何元素设置为边界框)。如果你能读懂 JS,jQuery UI 中的大部分代码都很清楚,所以它可能会对你有所帮助:jqueryui.com/demos/draggable/#constrain-movement
-
@Tim 谢谢。我实际上正在考虑阅读不同的库是如何做到的,但是当我查看其他人的代码时,我不知道发生了什么。我还没有足够的 JavaScript 知识。但是,我最后一次查看某人的“拖放”版本是在我编写自己的代码之前,所以链接很有可能会派上用场。如果只有代码被大量评论!此外,这些库可以帮助我了解如何构建代码。我想实现引擎,使其易于使用。
标签: javascript html css drag-and-drop