JavaScript拖拽问题

SJY发表于:2016年08月29日 16:30 • 阅读:

拖拽事件的 dragleave 父子元素之间的拖拽问题

  • 父元素为 wrap
  • 子元素为 inner
  • 事件绑定的元素为 wrap
<style>
#wrap{
    width:500px;
    height:500px;
    border:1px dashed #999;
}
#inner{
    width:300px;
    height:300px;
    background:#fc0;
}
.over{
background:#fcc;
}
</style>
<div id="wrap">
<div id="inner"></div>
</div>

<script>
var wrap=document.getElementById('wrap');
wrap.addEventListener('dragleave',function(e){
e.preventDefault();
wrap.className='';
},false)
wrap.addEventListener('dragenter',function(e){
e.preventDefault();
wrap.className='over';
},false)
</script>

在进入时用事件 dragenter 无论是到 wrap 或 直接到其子元素 inner 都能触发

离开时用事件 dragleave 只要移动到另一个元素,都会直接触发。

比如我进入时为 inner,只要鼠标拖动到 wrap 里,就直接触发了。

同样的,进入时 wrap,只要拖动到其子元素,也直接触发了。

问题是,我绑定的是父元素,我希望,只有离开 wrap 的范畴才触发,这个要怎么实现?

如果子元素不需要鼠标事件,只要能看到就可以的话,可以用CSS把子元素的鼠标事件关闭

.inner{
  pointer-events: none;
}

如果子元素需要用到鼠标事件,以上方法就不行了。

起初我想的是,dragenter 时给子元素添加关闭鼠标事件的样式,dragleave 时再恢复。

但问题在于,进入时,关闭了子元素的鼠标事件,那么子元素等于不存在了,就会直接跳到离开时状态。

如果你拖动文件反复的进入离开,就会发现闪屏(前提是父元素和子元素添加了背景色,且拖入时背景色改变),那是因为 关闭鼠标事件 和 恢复鼠标事件 几乎同时在进行。

如果子元素只在鼠标拖入时失效,离开马上恢复,可以另外新建一个蒙板,具体参见 JavaScript拖拽的实现

完美解决方案

<script>
var wrap=document.getElementById('wrap');
var lastenter;

wrap.addEventListener('dragenter',function(e){
e.preventDefault();
lastenter = e.target;//已进入,就用 e.target 获取目标对象(即父元素 wrap),并赋值给变量 lastenter
wrap.className='over';
},false);

wrap.addEventListener('dragleave',function(e){
e.preventDefault();
if (lastenter === e.target) {//只有当lastenter等于目标对象时,才去除class样式
        wrap.className='';
    }    
},false);

</script>

参考文献 http://stackoverflow.com/questions/10867506/dragleave-of-parent-element-fires-when-dragging-over-children-elements

欢迎转载,但请保留原文地址 http://www.sjyhome.com/javascript/1043.html

标签: 拖拽

回复(0)