天天看點

關于 JS 拖拽功能的沖突問題及解決方法

我在之前寫過關于 JS 拖拽的文章,實作方式和網上能搜到的方法大緻相同,别無二緻,但是在一次偶然的測試中發現,這種綁定事件的方式可能會和其它的拖拽事件産生沖突,由此産生了對于事件綁定的思考。本文主要介紹解決這種沖突的方法,其實就是事件綁定的時機問題。

這個問題是在類似如下 CodePen 例子中發現的,在有拖拽功能的頁面中添加一個原生 input range 元素,可以發現 input range 的拖拽失效了。

See the Pen drag with conflict issue by Zongbin (@nzbin) on CodePen.

讓我們看一下拖拽方法代碼:

幾乎網上的大部分拖拽案例都是上面這種綁定事件的方法。起初以為是 jQuery 事件綁定的問題,其實完全不相關,使用原生 JS 同樣會遇到這種問題。

再看一下拖拽的事件綁定,很明顯,在 document 上綁定的事件和 input range 的拖拽事件沖突了。其實,document 作為最上層的節點,它上面不應該綁定其它事件(事件代理除外),如果綁定,必須是臨時性綁定,否則一定會造成沖突。

知道問題所在之後,解決方法也非常簡單,其中參考了 jQuery UI 的處理方式。

我們可以在拖拽開始的時候綁定 document 的事件,然後在拖拽結束的時候移除 document 的事件。

下面 CodePen 中的 input range 已經可以正常拖動了。

See the Pen drag with conflict issue fixed by Zongbin (@nzbin) on CodePen.

我們可以通過控制台的 Event Listener 檢視綁定的事件,在平時的工作中,切記不要污染全局的預設事件。一般情況下,工作中并不會遇到本文所說的這一情況,但是如果真的碰到了,需要知道問題的所在。

感謝您的閱讀,如果您對我的文章感興趣,可以關注我的部落格,我是叙帝利,下篇文章再見!

開發低代碼平台的必備拖拽庫 https://github.com/ng-dnd/ng-dnd

基于 Angular Material 的中背景管理架構 https://github.com/ng-matero/ng-matero

Angular Material Extensions 擴充元件庫 https://github.com/ng-matero/extensions

仿 Windows 照片檢視器插件 https://github.com/nzbin/photoviewer

仿 Windows 照片檢視器插件 jQuery 版 https://github.com/nzbin/magnify

完美替代 jQuery 的子產品化 DOM 庫 https://github.com/nzbin/domq

簡化類名的輕量級 CSS 架構 https://github.com/nzbin/snack

與任意 UI 架構搭配使用的通用輔助類 https://github.com/nzbin/snack-helper

單元素純 CSS 加載動畫 https://github.com/nzbin/three-dots

有趣的 jQuery 卡片抽獎插件 https://github.com/nzbin/CardShow

懸疑科幻電影推薦 https://github.com/nzbin/movie-gallery

鍛煉記憶力的小程式 https://github.com/nzbin/memory-stake