基于Web API drap事件的简单拖拽功能
- 效果示例图
- 代码示例
效果示例图
代码示例
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><style type="text/css">* {padding: 0px;margin: 0px;box-sizing: border-box;}ul,ol,li {list-style: none;}.drag-wrap {width: 600px;margin: 20px auto;}.drag-header {border: 1px solid #dcdcdc;border-radius: 4px;width: 100%;display: flex;flex-wrap: wrap;}.drag-tab {border: 1px solid #00a2ef;border-radius: 4px;padding: 6px 12px;font-size: 16px;color: #00a2ef;margin: 6px 6px;cursor: move;}.drag-tab:hover {border: 1px solid #00a2ef;background-color: #00a2ef;color: #fff;}.drag-content {border: 1px solid #dcdcdc;width: 100%;margin-top: 60px;}.drag-title {border-bottom: 1px solid #00a2ef;width: 100%;display: flex;flex-direction: row;}.drag-th {border-right: 1px solid #dcdcdc;flex: 1;padding: 6px 6px;}.drag-th:last-child {border-right: 0px;}.drag-tr {border-bottom: 1px solid #00a2ef;width: 100%;display: flex;flex-direction: row;}.drag-tr:hover {background-color: #eee;}.drag-tr:last-child {border-bottom: 0px;}.drag-item-td {border-right: 1px solid #dcdcdc;flex: 1;padding: 12px 6px;}.drag-tr>.drag-item-td:last-child {border-right: 0px;}.drag-item-td-operate {display: flex;flex-wrap: wrap;}.move-enter {background-color: #dcdcdc;}.operate-btn {border: 1px solid #00a2ef;border-radius: 4px;padding: 6px 12px;font-size: 16px;color: #00a2ef;margin: 6px 6px;cursor: move;text-align: center;}</style></head><body><div class="drag-wrap"><!-- header --><div class="drag-header"><div class="drag-tab" draggable="true" data-id="1" data-effect="copy">毛利兰</div><div class="drag-tab" draggable="true" data-id="2" data-effect="copy">毛利小五郎</div><div class="drag-tab" draggable="true" data-id="3" data-effect="copy">英妃理</div><div class="drag-tab" draggable="true" data-id="4" data-effect="copy">工藤新一</div><div class="drag-tab" draggable="true" data-id="5" data-effect="copy">工藤优作</div><div class="drag-tab" draggable="true" data-id="6" data-effect="copy">毛利博士</div><div class="drag-tab" draggable="true" data-id="7" data-effect="copy">小岛元太</div><div class="drag-tab" draggable="true" data-id="8" data-effect="copy">黑羽快斗</div><div class="drag-tab" draggable="true" data-id="9" data-effect="copy">黑羽盗一</div><div class="drag-tab" draggable="true" data-id="10" data-effect="copy">中森青子</div></div><!-- content --><ul class="drag-content"><li class="drag-title"><div class="drag-th">ID</div><div class="drag-th">状态</div><div class="drag-th">性别</div><div class="drag-th">操作</div></li><li class="drag-tr"><div class="drag-item-td">001</div><div class="drag-item-td">上学中</div><div class="drag-item-td">男</div><div class="drag-item-td drag-operate" data-id="001" data-drop="copy"></div></li><li class="drag-tr"><div class="drag-item-td">002</div><div class="drag-item-td">上学中</div><div class="drag-item-td">男</div><div class="drag-item-td drag-operate" data-id="002" data-drop="copy"></div></li><li class="drag-tr"><div class="drag-item-td">003</div><div class="drag-item-td">上学中</div><div class="drag-item-td">女</div><div class="drag-item-td drag-operate" data-id="003" data-drop="copy"></div></li><li class="drag-tr"><div class="drag-item-td">004</div><div class="drag-item-td">研发中</div><div class="drag-item-td">男</div><div class="drag-item-td drag-operate" data-id="004" data-drop="copy"></div></li></ul></div></body><script type="text/javascript">const dragContainer = document.querySelector(".drag-wrap");//暂存原始节点let sourceNode = null;//是否离开let dragLeave = false;dragContainer.addEventListener("dragstart", (e) => {console.log("[dragstart]", e.target)//DataTransfer.effectAllowed 属性指定拖放操作所允许的一个效果e.dataTransfer.effectAllowed = e.target.dataset.effect;sourceNode = e.target;})/*** 拖拽的元素悬浮在元素上,触发事件* **/dragContainer.addEventListener("dragover", (e) => {e.preventDefault()})/*** 判断当前节点或者它的父节点是否设置了data-drop="copy"* **/function judgeDropNode(node) {while (node) {// 先判断当前节点是否包含data-drop="copy"if (node.dataset && node.dataset.drop === 'copy') {return node;}//在判断它的父节点是否存在data-drop="copy"node = node.parentNode}}/*** 拖拽的元素进入某个元素触发事件* **/dragContainer.addEventListener("dragenter", (e) => {console.log("[dragenter]", e.target)clearStyle();const dropNode = judgeDropNode(e.target);console.log("[node]", dropNode)if (dropNode && (dropNode.dataset.drop === e.dataTransfer.effectAllowed)) {dropNode.classList.add("move-enter");}})/*** 拖拽的元素放手了之后触发的事件* **/dragContainer.addEventListener("drop", (e) => {console.log("[drop]", e.target)const dropNode = judgeDropNode(e.target);console.log("[node]", dropNode)if (dropNode && (dropNode.dataset.drop === e.dataTransfer.effectAllowed)) {if (dropNode.dataset.drop === 'copy') {const btn = document.createElement("div");btn.classList.add("operate-btn");btn.innerText = sourceNode.innerText;btn.dataset.id = sourceNode.dataset.id;dropNode.appendChild(btn);eventHandle(sourceNode.dataset.id, dropNode.dataset.id);}}})/*** 拖拽离开* **/dragContainer.addEventListener("dragleave", (e) => {console.log("[dragleave]", e.target)})/*** 拖拽结束* **/dragContainer.addEventListener("dragend", (e) => {console.log("[dragend]", e.target)clearStyle();})//清除原来添加的样式function clearStyle() {document.querySelectorAll(".drag-operate").forEach(item => {item.classList.remove("move-enter");});}function eventHandle(id, parentID) {console.log("[]", id, parentID)}</script>
</html>
drap API