拖放是很常見的一種交互效果,不少時候咱們都會藉助於第三方的控件來實現,其實用原生js實現起來也很是的方便。接下來咱們就用原生js和css快速實現這樣的拖放效果:css
HTML的內容很簡單,就是五個空的容器和一個能夠被拖拽的元素:html
html:app
<body> <div class="droppable"> <div class="draggable" draggable="true"></div> </div> <div class="droppable"></div> <div class="droppable"></div> <div class="droppable"></div> <div class="droppable"></div> </body>
注意點: 1. 容器的的class
爲droppable
,用於接收被拖拽的元素,可被拖拽的元素class
爲draggable
,同時設置draggable
屬性爲true
,表示該元素能夠被拖拽。 2. 默認狀況下,只有圖片、連接還有被選中的文字能被拖拽,其餘元素須要設置draggable
爲true
才能被拖拽。因此爲了凸顯draggable
的用法,這裏使用<div>
而不是<image>
來做爲被拖拽的元素。
在實現樣式的時候,除了實現靜態的樣式,一些過渡狀態也須要增長樣式以提高視覺體驗:1. 元素被拖動的過程當中增長邊框等效果;2. 當元素被拖動到容器上方時,容器也應增長樣式代表容器能夠接收一個被拖拽的元素。dom
css:
異步
body { background-color: darksalmon; } .draggable { background-image: url('http://source.unsplash.com/random/150x150'); position: relative; height: 150px; width: 150px; top: 5px; left: 5px; cursor: pointer; } .droppable { display: inline-block; height: 160px; width: 160px; margin: 10px; border: 3px salmon solid; background-color: white; } .dragging { border: 4px yellow solid; } .drag-over { background-color: #f4f4f4; border-style: dashed; } .invisible { display: none; }
注意點: 1. 圖片來源於https://source.unsplash.com/
的隨機圖片; 2..dragging
爲draggable元素正在被拖動的狀態,增長黃色border; 3..drag-over
爲draggable元素被拖動到容器上方時容器的狀態,增長灰色虛線border。
最後,咱們須要經過js監聽draggable
和droppable
的相關的事件。this
js:url
// 查詢draggable和droppable const draggable = document.querySelector('.draggable'); const droppables = document.querySelectorAll('.droppable'); // 監聽draggable的相關事件 draggable.addEventListener('dragstart', dragStart); draggable.addEventListener('dragend', dragEnd); function dragStart() { this.className += ' dragging'; setTimeout(() => { this.className = 'invisible'; }, 0); } function dragEnd() { this.className = 'draggable'; } // 監聽droppable的相關事件 for (const droppable of droppables) { droppable.addEventListener('dragover', dragOver); droppable.addEventListener('dragleave', dragLeave); droppable.addEventListener('dragenter', dragEnter); droppable.addEventListener('drop', dragDrop); } function dragOver(e) { e.preventDefault(); } function dragEnter(e) { e.preventDefault(); this.className += ' drag-over'; } function dragLeave(e) { this.className = 'droppable'; } function dragDrop(e) { this.className = 'droppable'; this.append(draggable); }
注意點: 1. 當draggable元素被拖動時,原來容器中的draggable元素並不會消失,須要咱們手動將其隱藏(class
設置爲invisible
),若是同步操做會立馬觸發dragend
事件致使拖動效果消失,因此在setTimeout
的回調中異步設置可確保拖動操做開始後再隱藏draggable元素; 2. 在dragEnter
和dragOver
方法中咱們須要經過preventDefault
來取消事件以代表容器是一個合法的droppable
元素,否則容器的drop
事件將沒法觸發,接下來的操做也將沒法進行,詳細解釋請參考 MDN DropTarget; 3. 在dragDrop
方法中直接使用append
方法將draggable
元素移動至當前容器下面。
好了,demo比較簡單,可是細節仍是有一些的,本身實踐一下才能更深入的領悟。spa
完整示例:https://codepen.io/mudontire/...code