HTML5 拖拽接口

1.首先,为了使元素可拖动,要先设置元素为可拖拽

  • 方法:添加draggable属性,设置为 true
  • 注意:链接和图像默认就支持拖拽,另外,如果一个元素中的文本被选中,那么这个元素和他的文本节点此时都支持被拖拽。
<body style="padding:30px;">
    <div class="item">
        <h3 draggable="true">我是被允许拖拽的h3元素</h3>
    </div>
    <div class="item">
        <a href="http://www.baidu.com/">a链接</a>
    </div>
    <div class="item">
        <img src="timg.jpg" alt="" width="200">
    </div>
    <div class="item">
        <h3>选中文字后可被拖拽</h3>
    </div>
</body>
<script>
    document.ondragstart = function(){
        console.log('dragstart')
    }
</script>

2.拖拽事件监听

  • 拖拽事件一律使用(推荐)document监听,拖拽事件分2种,一种针对的是被拖拽的元素,第二种针对被拖拽的元素经过的容器
事件名称 事件对象(e.target) 说明
ondrag 被拖拽的元素 元素被拖拽期间(持续)触发
ondragstart 被拖拽的元素 开始拖拽元素时触发(推荐使用它记录被拖拽的元素)
ondragend 被拖拽的元素 元素拖拽结束时触发
ondragenter 接收容器 被拖拽的元素进入当前容器范围内时触发此事件
ondragover 接收容器 被拖拽的元素停留在当前容器范围内(持续)触发此事件
ondragleave 接收容器 被拖拽的元素离开当前容器范围内时触发此事件
ondrop 接收容器 释放鼠标键时触发此事件(触发时间早于ondragend)

  • 注意:浏览器默认阻止ondrop事件,需要在ondragover事件中阻止默认事件它才能被触发

3.完整的拖拽实例

  • 哪个元素被拖拽:可以在ondragstart事件中获取被拖拽的元素,并保存,问题1解决
  • 哪个容器负责接收:实际操作中,拖拽结束时经过的容器就是接收的容器,而能在此时获得接收容器的事件只能是drop事件(而drop事件默认被屏蔽,所以需要在ondragover事件中释放此事件)
<script>
    // 设置全局变量记录被拖拽的元素
    var dragNode = null
    // 监听拖拽开始,记录被拖拽的元素
    document.ondragstart = function (e) {
        //记录被拖拽的元素
        dragNode = e.target
        // 修改通明度
        dragNode.style.opacity = 0.5
    }
    // 监听拖拽结束
    document.ondragend = function (e) {
        // 恢复透明度
        e.target.style.opacity = 1
        // 清空dragNode
        dragNode = null
    }
    // 阻止默认事件
    document.ondragover = function (e) {
        //允许被拖拉的节点放入目标节点
        e.preventDefault()
    }
    // 监听拖拽释放,获取当前容器
    document.ondrop = function (e) {
        // 获取释放时的容器
        var targetBox = e.target
        // 判断是否是目标容器
        if(targetBox.matches(".box")){
            // 将元素移动到新的容器中
            targetBox.appendChild(dragNode)
        }
    }
</script>

4.优化

  • 存在的问题:前面的案例中我们使用了一个全局变量来存储被拖拽的元素,但是使用全局变量容器污染全局
  • 解决办法:在拖拽事件中,事件对象event有一个dataTransfer属性对象,用来保存和读取拖放相关的数据
方法 说明
e.dataTransfer.setData(key,data) 设置数据(只能传入数字或者字符串)
e.dataTransfer.getData(key) 取数据(数字或者字符串)
e.dataTransfer.clearData(key) 清空数据

  • 代码实现:使用e.dataTransfer记录被拖拽元素的id属性值,从而通过这个值获取获取到被拖拽的元素
<script>
    // 监听拖拽开始,记录被拖拽的元素
    document.ondragstart = function (e) {
        //判断节点是元素节点且有id属性,没有则赋予一个id
        if(!e.target.id && e.target.nodeType === 1){
            // 如果没有id,则设置一个id
            e.target.id = "dragTest"
        }
        //保存id信息
        e.dataTransfer.setData("id",e.target.id)
        // 修改通明度
        e.target.style.opacity = 0.5
    }
    // 监听拖拽结束
    document.ondragend = function (e) {
        // 恢复透明度
        e.target.style.opacity = 1
    }
    // 阻止默认事件
    document.ondragover = function (e) {
        //允许被拖拉的节点放入目标节点
        e.preventDefault()
    }
    // 监听拖拽释放,获取当前容器
    document.ondrop = function (e) {
        // 获取释放时的容器
        var targetBox = e.target
        // 根据存储的数据获取被拖拽的元素
        var id = e.dataTransfer.getData("id")
        var dragNode = document.querySelector("#"+id)
        // 判断是否是目标容器
        if(targetBox.matches(".box")){
            // 将元素移动到新的容器中
            targetBox.appendChild(dragNode)
        }
    }
</script>
posted @ 2019-09-30 14:20  ---空白---  阅读(318)  评论(0编辑  收藏  举报