首页 > JS怎么实现子元素mousedown不触发父元素的click事件

JS怎么实现子元素mousedown不触发父元素的click事件

因一个需求需要做父元素做点击事件,子元素有拖动事件,但是现在的父元素的点击事件影响了拖动,我做了一个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事件处理有三个阶段:

  1. 捕捉阶段(capture phase):从最上层元素,直到最下层(你点击的那个target)元素。路过的所有节点都可以捕捉到该事件。
  2. 命中阶段(target phase):如果该事件成功到达了target元素,它会进行事件处理。
  3. 冒泡阶段(bubbling phase):事件从最下层向上传递,依次触发父元素的该事件处理函数。

在任意一个阶段的事件处理函数中,都可以通过调用event.stopPropagation来中断事件流,后续的阶段将不会被调用。

其实return false做了三件事:

  1. stopPropagation():阻止事件传播
  2. preventDefault():禁止浏览器默认行为,比如<a>标签被点击后页面会跳转
  3. 立即结束当前函数并返回,当然。

你还可以通过delegate实现更加高效和简洁的事件处理过程,具体可以看这篇文章:

jQuery事件:bind、delegate、on

【热门文章】
【热门文章】