拖拽
使用 HTML5 的 draggable 属性可以简单地实现元素的拖拽效果,无需编写 JavaScript 代码。
可拖拽对象
给元素添加 draggable="true" 属性:
1 2 3
| <div draggable="true" id="draggable"> This element is draggable </div>
|
这就使得该元素可以拖拽了。
然后可以监听 drag 相关事件:
1 2 3 4 5 6 7 8 9
| const draggable = document.getElementById('draggable');
draggable.addEventListener('dragstart', () => { console.log('开始拖拽'); });
draggable.addEventListener('dragend', () => { console.log('拖拽结束'); });
|
dragstart 在拖拽开始时触发,dragend 在拖拽结束时触发。
可以通过 event.dataTransfer.setData() 在拖拽时携带数据:
1 2 3
| draggable.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text', '拖拽的数据'); });
|
DIV设置draggable="true"后,内部的元素就算设置draggable="false",也依旧会被拖动。
所以
我们可以设置可拖动的元素尽可能是满足需求的最小DIV。
拖拽目标对象
拖拽的目标DOM要添加两个监听
有的元素会默认阻止drop事件,所以这里阻止默认事件让drop事件正常触发。
1 2 3
| dropzone.addEventListener('dragover', (e) => { e.preventDefault(); });
|
然后在 drop 元素的ondrop事件中读取数据:
1 2 3 4
| dropzone.addEventListener('drop', (e) => { const data = e.dataTransfer.getData('text'); console.log(data); });
|
通过 HTML5 的 API 可以轻松实现拖拽交互,无需处理鼠标事件的细节。
注意
不建议使用拖拽实现DIV的移动功能,如果拖拽的目标位置有遮挡,就会导致拖拽回调的位置是错误的。
拖拽离开(取消拖拽)的事件
1 2 3 4
| mid_div.addEventListener("dragleave", () => { console.log("拖拽离开"); window.placeholder_div.style.display = "none"; });
|
拖拽的时候鼠标离开拖拽区域不会触发mouseleave事件,所以要用dragleave。
1 2
| mid_div.addEventListener("mouseleave", function (e) { });
|
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let homeDom = document.querySelector(".home"); homeDom.addEventListener("dragstart", (e) => { e.dataTransfer.setData("id", e.target.dataset.id); console.info("拖动元素的ID:" + e.target.dataset.id); });
homeDom.addEventListener("dragover", (e) => { e.preventDefault(); }); homeDom.addEventListener("drop", (e) => { const id = e.dataTransfer.getData("id"); console.info("拖动元素的ID:" + id); if (e.target.classList.contains("znode")) { console.info("目标元素的ID:" + e.target.dataset.id); } });
|
事件
DOM元素添加事件
JS可以通过以下几种方式给DOM元素添加事件:
使用元素的事件属性:
1 2 3 4
| let btn = document.getElementById('myBtn'); btn.onclick = function() { }
|
使用元素的addEventListener()方法:
1 2 3 4
| let btn = document.getElementById('myBtn'); btn.addEventListener('click', function(event) { });
|
新元素也能触发事件
我们可以把事件添加到父元素上,事件获取到的DOM是最子层的DOM,我们可以找到最近的夫元素,来进行逻辑处理。
1 2 3 4
| <div class="leftbar"> <div class="leftbar_item" data-type="zimg" draggable="true"><img src="./imgs/005.jpg" alt=""></div> <div class="leftbar_item" data-type="ztext" draggable="true">测试文字</div> </div>
|
添加事件
1 2 3 4 5 6 7 8
| let leftbar = document.querySelector(".leftbar"); leftbar.addEventListener("click", function (event) { let targetElement = event.target; const closestParent = targetElement.closest('.leftbar_item'); if (closestParent) { console.log(closestParent.dataset.type); } })
|
事件根据样式判断
1 2 3 4 5
| leftbar.addEventListener("click", (e) => { if (e.target.classList.contains("leftbar")) {
} })
|