JavaScript拖拽2——多元素、分离JS

上一节我们实现了基本的拖拽,但是需要给可拖拽的元素设置一个特定的id,然后再在JS中修改代码,使用起来比较麻烦。这样一旦文档结构发生变化就要调整JS代码,没有做到JavaScript与HTML分离的原则。

所以应该实现一个可以适用于多个元素的拖拽代码,而且代码在可拖拽元素改变后应该不需要修改而仍然能正常工作。

使用class做“钩子”

为了使代码适用于多个元素,我们使用它的class来指定元素是否可以拖拽。我们使用如下的JavaScript代码来遍历文档中所有的节点,然后让class为drag的元素可以被拖拽。

function dragInit(node){
if(node.className == "drag"){
node.onmousedown = down;
node.onmousemove = move;
node.style.position = "relative";
node.style.top = "0px";
node.style.left = "0px";
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}

dragInit函数会逐个检查各个节点的class是否为drag,如是是,那么会为该元素设置鼠标经过、鼠标按下事件的响应函数。

多个元素一起移动的问题

上面我们已经实现了多个元素可移动的问题。可以进入这个网页测试一下。可以发现这个拖拽效果有一个严重的问题。当我们拖动div1的时候,如果鼠标路径经过了div2,那么两个div会同时移动。原因是这触发了div2的onmouseover事件。我们可以通过给元素设置z-index的方法来解决。因为当我们拖动z-index较高的元素经过z-index较低的元素时并不会触发z-index较低元素的鼠标经过事件。所以我们对代码做出如下修改:

<script type="text/javascript">
var max = 1;//定义一个max变量 ……其它部分不变 function down(event)
{
…… //保证点击元素的z-index最高
this.style.zIndex = max++;
}
</script>

我们设置了一个max变量来记录当前的z-index值,当点击一个元素的时候就用max的值来设置它的z-index属性,同时max的值会变大。这样就实现了每次拖拽一个元素的时候,不会触发其它元素的mouseover事件。但是,

我们发现,当拖动元素的速度非常快的时候,仍然会造成两个元素一起移动。我个人认为这是浏览器处理事件的延迟造成的。通过给每个对象分别设置一个判断拖拽状态的布尔变量dragging就可以解决这个问题了。最终的代码如下:

拖拽JavaScript代码

<script type="text/javascript">
var dragging = false;
var mouseY;
var mouseX;
var max = 1;
function dragInit(node){
if(node.className == "drag"){
node.onmousedown = down;
node.onmousemove = move;
node.onmouseover = over;
node.onmouseup = up;
node.style.position = "relative";
node.style.top = "0px";
node.style.left = "0px";
node.dragging = false;
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}
window.onload = function(){
dragInit(document);
document.onmouseup = docUp;
}
function down(event)
{
event = event || window.event;
dragging = true;
this.dragging = true;
mouseX = parseInt(event.clientX);
mouseY = parseInt(event.clientY);
objY = parseInt(this.style.top);
objX = parseInt(this.style.left);
this.style.zIndex = max++;
}
function move(event){
event = event || window.event;
if(this.dragging == true && dragging == true){
var x,y;
y = event.clientY - mouseY + objY;
x = event.clientX - mouseX + objX;
this.style.top = y + "px";
this.style.left = x + "px";
}
}
function up(){
this.dragging = false;
}
function docUp(){
dragging = false;
}

function over(){
this.style.cursor = "move";
}
</script>

做出修改的代码用已经标记了出来。点击进入示例网页

JavaScript拖拽系列

  1. JavaScript拖拽
  2. JavaScript拖拽2——多元素、分离JS
  3. JavaScript拖拽3——解决快速拖拽的问题
  4. JavaScript拖拽4——获得元素的位置
  5. JavaScript拖拽5——性能优化
  6. JavaScript拖拽6——修复错误

 

  1. 用javascript修改html元素的class
  2. JavaScript重定向
  3. JavaScript对象当作关联数组
  4. JavaScript弹出窗口以及窗口间的通信
  5. JavaScript显示信息实例
  6. 用JavaScript批量访问HTML元素
  7. 分离JavaScript与HTML
  8. JavaScript计算器实例
  9. JavaScript的Math对象计算器
  10. JavaScript改变HTML元素的位置
  11. JavaScript动画
  12. JavaScript动画函数
  13. JavaScript拖拽
  14. JavaScript拖拽2——多元素、分离JS
  15. JavaScript拖拽3——解决快速拖拽的问题
  16. addEventSimple函数,添加事件响应函数的方法
  17. addEventSimple观察鼠标事件
  18. JavaScript click事件深入
  19. JavaScript事件来源元素
  20. JavaScript修改与访问CSS
  21. JavaScript拖拽4——获得元素的位置
  22. JavaScript拖拽5——性能优化
  23. DOM Scripting相册
  24. DOM Scripting斑马表格
  25. DOM Scripting动画切图
  26. JavaScript颜色渐变
  27. JavaScript拖拽6——修复错误