HTML5拖拽事件

在网页中,拖放是一个很常见的一个用户界面模式。简单来说,就是鼠标点击目标元素不放,移动鼠标位置,然后松开鼠标,即可将目标元素移动到另一个区域。它的实现其实很简单。以下介绍两种常见的实现方法。

使用onmouse事件实现拖放

通过监听鼠标事件实现元素拖放:必须借用onmousedownonmousemoveonmouseup三个事件实现,且三者的顺序不能乱。

  • onmousedown:鼠标按下事件,一般用在拖放元素上。
  • onmousemove:鼠标移动事件,一般用在document或者window上。
  • onmouseup:鼠标抬起事件,同上。

具体实现如下:

//获取拖放元素
var img = document.getElementById('img');
//记录鼠标点击位置和元素边界的距离
var dirX = 0,dirY = 0; 
//给元素添加监听事件
img.onmousedown = function(e) {
  dirX = e.clientX - img.offsetLeft;
    dirY = e.clientY - img.offsetTop;
  document.onmousemove = function(e) {
    //记录鼠标移动距离
    let moveX, moveY; 
    moveX = e.clientX - dirX;
    moveY = e.clientY - dirY;
    //处理边界问题
    if (moveX < 0) {
      moveX = 0
    } else if (moveX > window.innerWidth - img.offsetWidth) {
      moveX = window.innerWidth - img.offsetWidth
    }
    if (moveY < 0) {
      moveY = 0
    } else if (moveY > window.innerHeight - img.offsetHeight) {
      moveY = window.innerHeight - img.offsetHeight
    };
    //实时的改变元素位置
    img.style.left = moveX + 'px';
    img.style.top = moveY + 'px'
  }
  //监听鼠标抬起事件
  document.onmouseup = function(e) {
    //事件取消
    document.onmouseup = document.onmousemove = null
  }
}

使用HTML5Drag实现拖放

拖拽元素时,将依次发生以下事件:

  • ondragstart
  • ondrag:拖拽期间持续触发该事件
  • ondragend

在目标元素(放置目标元素)上将会发生以下事件:

  • ondragenter:元素进入目标元素
  • ondragover:元素在目标元素之中移动
  • ondragleave/ondrop:元素离开目标元素/鼠标抬起

dataTransfer 对象:使用该对象进行数据传输

  • setData:接收两个参数:第一个参数设置传输数据的类型:text 或者 URL,第二个参数设置值
  • getData:接收值,只发生在ondrop

dropEffecteffectAllowed :通过dataTransfer对象还可以确定被拖拽元素以及放置目标的元素能够接受什么操作。其中dropEffect可以知道被拖拽元素可以执行那种放置行为。effectAllowed可以知道允许拖拽元素执行哪种dropEffect

effectAllowed有四种值:

  • “none”:不能把拖动的元素放在这里。这是除文本框之外所有元素的默认值。
  • “move”:应该把拖动的元素移动到放置目标。
  • “copy”:应该把拖动的元素复制到放置目标。
  • “link”:表示放置目标会打开拖动的元素(但拖动的元素必须是一个链接,有 URL)。

要使用 dropEffect 属性,必须在 ondragenter 事件处理程序中针对放置目标来设置它。

effectAllowed的属性值如下:

  • “uninitialized”:没有给被拖动的元素设置任何放置行为。
  • “none”:被拖动的元素不能有任何行为。
  • “copy”:只允许值为”copy”的 dropEffect。
  • “link”:只允许值为”link”的 dropEffect。
  • “move”:只允许值为”move”的 dropEffect。
  • “copyLink”:允许值为”copy”和”link”的 dropEffect。
  • “copyMove”:允许值为”copy”和”move”的 dropEffect。
  • “linkMove”:允许值为”link”和”move”的 dropEffect。
  • “all”:允许任意 dropEffect。

必须在 ondragstart 事件处理程序中设置 effectAllowed 属性

使用HTML5Drag事件来实现自由拖拽,具体实现如下:

var EventUtil = {
    /**
     * 绑定事件
     * @param { type } = { 事件类型 }  
     * @param { callback }  = { 回调函数 } 
     * @param { bool }   = { 指定事件是否在捕获或冒泡阶段执行。true - 事件句柄在捕获阶段执行。默认,事件句柄在冒泡阶段执行 }
     * */
    addHandler: function(el, type, callback, bool = false) {
        if (el.addEventListener) {
            el.addEventListener(type, callback, bool)
        } else if (el.attachEvent) {
            e.attactEvent('on' + type, callback)
        } else { //默认使用DOM0级的事件
            el['on' + type] = callback;
        }
    },
}
var img = document.getElementById('img');
//记录鼠标点击位置和边界的距离
var dirX = 0,dirY = 0; 
var dirX, dirY;
EventUtil.addHandler(img, 'dragstart', function(e) {
  console.log(e, '开始拖拽');
  dirX = e.clientX - img.offsetLeft;
  dirY = e.clientY - img.offsetTop;
  console.log(dirX, dirY);
});
EventUtil.addHandler(window, 'dragenter', function(e) {
  console.log('进入目标元素');
});
EventUtil.addHandler(window, 'dragover', function(e) {
  // console.log('在目标元素中移动');
  //计算鼠标移动距离
  let moveX = moveY = 0;
  moveX = e.clientX - dirX;
  moveY = e.clientY - dirY;
  //边界处理
  if (moveX < 0) {
    moveX = 0
  } else if (moveX > (window.innerWidth - img.offsetWidth)) {
    moveX = window.innerWidth - img.offsetWidth
  }
  if (moveY < 0) {
    moveY = 0
  } else if (moveY > (window.innerHeight - img.offsetHeight)) {
    moveY = window.innerHeight - img.offsetHeight
  }
  img.style.left = moveX + 'px';
  img.style.top = moveY + 'px';
  //阻止默认行为
  EventUtil.preventDefault(e)
});
EventUtil.addHandler(window, 'dragleave', function(e) {
  console.log('离开目标元素');
});
EventUtil.addHandler(window, 'drop', function(e) {
  //设置磁吸效果
  if (e.clientX > (window.innerWidth / 2)) {
    img.style.left = window.innerWidth - img.offsetWidth + 'px'
  } else {
    img.style.left = 0 + 'px';
  }
  // console.log(e,'drop');
  // let data = e.dataTransfer.getData('text');
  // console.log('drop');
  // EventUtil.removeHandler()
  // e.target.appendChild(document.getElementById(data))
});

拖放事件流程

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!