sortablejs 支持 iframe 跨域拖拽

背景

最近研究拖拽生成頁面,遇到一個跨iframe拖拽的功能的問題。在此記錄下心得。git

頁面裏面的 iframe 在沒有跨域的狀況下,SortableJS 是支持跨iframe拖拽的,官方倉庫給了例子。若是跨域了,咱們拿不到 iframe 的 contentDocument,沒法監聽事件,因此 Sortable 默認狀況下是不能工做的。github

思路 - 模擬拖拽

理論上 Sortable 是經過監聽事件來完成拖拽的功能,咱們手動構造 drag 事件,通知 Sortable,也是能夠完成任務的。跨域

實踐 - 模擬拖拽

拖拽須要處理三個事件節點dom

  • dragstart
  • dragover
  • dragend

dragstart

Sortable 一開始不會在 dom 節點加上 draggable 屬性,必須點擊了纔會,因此模擬時,須要先觸發一個 pointdown 事件,而後觸發 dargstrat 事件post

var downEvent = new PointerEvent("pointerdown", {
 //    pointerId: 1,
 bubbles: true,
 cancelable: true,
 // pointerType: "touch",
 width: 100,
 height: 100,
 isPrimary: true,
});
var startE = new DragEvent("dragstart", { bubbles: true });

dragover

父頁面的 dragover 事件不會傳遞到 iframe 內(廢話),因此咱們只能在 iframe 內監聽 mousemove 事件, 而後構造一個 dragover 事件,傳遞給dom,告訴 Sortable 咱們拖動了Sortable元素到該dom上面,看看是否是須要改變位置。spa

document.addEventListener("mousemove", (e) => {
 console.log(e.type);
 if (e.target.classList.contains("list-group-item")) {
     e.target.dispatchEvent(
     new DragEvent("dragover", { clientY: e.clientY, bubbles: true }) ); // 用mousemove代替
 }
})

dragend

觸發被拖拽 dom 的 dragend 事件便可code

dragEl.dispatchEvent(new DragEvent("dragend"));

父子頁面通信

在頁面中模擬拖拽成功後,接下來就是分開成兩個頁面,經過 postMessage 通信事件

隱藏的 Sortable 實例

這裏把隱藏的 Sortable 實例稱做影子節點, 在父頁面開始拖拽某個 dom 時,iframe 內部須要同時觸發一個 pull mode 的拖拽開始事件,而且將父頁面拖拽的 dom 的 innerHTML 寫入到影子節點get

demo 代碼

https://github.com/larry011/s...iframe

相關文章
相關標籤/搜索