因一个需求需要做父元素做点击事件,子元素有拖动事件,但是现在的父元素的点击事件影响了拖动,我做了一个demo,请问各路大侠们,如何对#idDrag的mouseup放开后不触发#DragContent的点击事件呢。
PS :鄙人使用了另一个比较笨的方法解决的,#idDrag拖动的时候就注销了#DragContent的click事件,#idDrag拖动结束(mouseup)后再重新绑定#DragContent的click事件。
感谢各位的细心回答,click时间是可以通过stopPropagation()阻止冒泡,但是我的我的用例是如果 $('#idDrag')绑定的是mousedown事件,不想出发父元素的click事件,该如何做到呢?
DEMO CODE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>简易拖放效果</title>
</head>
<body>
<script>
var isIE = (document.all) ? true : false;
var $ = function (id) {
return "string" == typeof id ? document.getElementById(id) : id;
};
var Class = {
create: function() {
return function() { this.initialize.apply(this, arguments); }
}
}
var Extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
}
var Bind = function(object, fun) {
return function() {
return fun.apply(object, arguments);
}
}
var BindAsEventListener = function(object, fun) {
return function(event) {
return fun.call(object, (event || window.event));
}
}
function addEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, true);
} else if (oTarget.attachEvent) {
oTarget.attachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = fnHandler;
}
};
function removeEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, true);
} else if (oTarget.detachEvent) {
oTarget.detachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = null;
}
};
//拖放程序
var SimpleDrag = Class.create();
SimpleDrag.prototype = {
//拖放对象,触发对象
initialize: function(drag) {
this.Drag = $(drag);
this._x = this._y = 0;
this._fM = BindAsEventListener(this, this.Move);
this._fS = Bind(this, this.Stop);
this.Drag.style.position = "absolute";
addEventHandler(this.Drag, "mousedown", BindAsEventListener(this, this.Start));
},
//准备拖动
Start: function(oEvent) {
console.log("idDrag event", oEvent.target.id);
oEvent.preventDefault();
oEvent.stopPropagation();
this._x = oEvent.clientX - this.Drag.offsetLeft;
this._y = oEvent.clientY - this.Drag.offsetTop;
//addEventHandler(document, "mousemove", this._fM);
//addEventHandler(document, "mouseup", this._fS);
},
//拖动
Move: function(oEvent) {
this.Drag.style.left = oEvent.clientX - this._x + "px";
this.Drag.style.top = oEvent.clientY - this._y + "px";
},
//停止拖动
Stop: function() {
removeEventHandler(document, "mousemove", this._fM);
removeEventHandler(document, "mouseup", this._fS);
}
};
</script>
<div id="DragContent" style="width:500px;height:500px; background:#efefef;">
<div id="idDrag" style="border:5px solid #0000FF; background:#C4E3FD; width:50px; height:50px;"></div>
</div>
<script>
new SimpleDrag("idDrag");
document.getElementById("DragContent").addEventListener("click", function(event){
console.log("DragContent event", event.target.id);
event.stopPropagation();
event.preventDefault();
}, true);
</script>
我想按住拖动元素放开了不触发DragContent的点击事件
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>简易拖放效果</title>
<style>
#DragContent{
width:500px;
height:500px;
background:#efefef;
position: relative;
}
#idDrag {
position: absolute;
top: 0;
left: 0;
border: 5px solid #0000ff;
background: #c4e3fd;
width: 50px;
height: 50px;
}
</style>
</head>
<body>
<div id="DragContent">
<div id="idDrag"></div>
</div>
我想按住拖动元素放开了不触发DragContent的点击事件
<script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
<script>
$(document).ready(function(){
$('#DragContent').bind('click', function(){
console.log('dragcontent');
});
$('#idDrag').bind('click', function(){
console.log('iddrag');
return false;
});
});
</script>
</body>
</html>
用 jquery 实现了下, 没用拖动事件, 但是逻辑都是一样的, 可以改写成原生的 js , 实现方式就是在绑定 iddrag 事件的时候, 使用 return false 返回, 这样就不会继续像下触发, 所以 dragcontent 就不会被执行
同意楼上的return false
。DOM事件处理有三个阶段:
- 捕捉阶段(capture phase):从最上层元素,直到最下层(你点击的那个target)元素。路过的所有节点都可以捕捉到该事件。
- 命中阶段(target phase):如果该事件成功到达了target元素,它会进行事件处理。
- 冒泡阶段(bubbling phase):事件从最下层向上传递,依次触发父元素的该事件处理函数。
在任意一个阶段的事件处理函数中,都可以通过调用event.stopPropagation
来中断事件流,后续的阶段将不会被调用。
其实return false
做了三件事:
-
stopPropagation()
:阻止事件传播 -
preventDefault()
:禁止浏览器默认行为,比如<a>
标签被点击后页面会跳转 - 立即结束当前函数并返回,当然。
你还可以通过delegate
实现更加高效和简洁的事件处理过程,具体可以看这篇文章:
jQuery事件:bind、delegate、on