不想當Window的Dialog不是一個好Modal,彈窗翻身記
彈窗是我們熟視無睹的一種交互方式,經常用到,但從沒好好想過這種交互行為背後的意義...
彈窗是Windows的靈魂
Windows的靈魂是什麼?當然是Window,當方便快捷的多窗口進入人們視野的時候,大家無不為之驚呼太好用了!!
彈窗其實是一種多執行緒
當你需要保持當前任務運行,同時開啟一個新任務時,就需要多執行緒。彈窗何嘗不是一種交互領域的多執行緒?它可以掛起當前的操作流,然後開闢一片全新的操作區域,讓用戶重新開始一條新的操作流,並且等待其完成後還可以重新返回之前的操作環境。
彈窗其實就是Page
有的UI設計師討厭彈窗,覺得不美觀,我不知道為什麼?當你把一個彈窗放到最大,充滿整個視口,你會發現這不就是一個所謂的Page嗎?
彈窗是一種keep-alive
為了保持當前的滾動位置,用戶的操作環境等,最簡單的辦法就是使用彈窗,不銷毀底下的Dom元素,這不就是keep-alive嗎?
彈窗與Window
Window?Dialog?Modal?傻傻分不清楚,我也分不清楚,但我們也不用去杠,就是一個命名而已。我們可以約定,Window特指那些重量級的彈窗,而Dialog和Modal特指輕量級彈窗。
我們借用瀏覽器的Tab窗口來看:
- Window裡面裝的是獨立的Page,而Dialog裡面裝的是一個獨立的Fragment;
- Window裡面不僅Dom元素是獨立的,運行環境也是獨立的,而Dialog只是Dom元素獨立;
- Window擁有獨立的歷史記錄棧,可以前進/後退/刷新,而Dialog沒有這些功能;
沒有Window的SPA是不完整的
我們習慣用Single-Page-Application來模擬瀏覽器的多頁,從而可以更自由的控制頁面間的跳轉體驗,但一直缺乏一種對Window窗口的模擬。在多頁中我們可以一句話讓一個頁面在新窗口中打開,比如:<a href="xxx" target="_blank">或者window.open(xxx),然而在SPA中即便是操作一個Dialog都是相對麻煩的事情,況且Dialog也不能算是Window。
實現虛擬Window
基於以上分析,個人實現了一個基本能滿足需求的虛擬Window。
先看看效果:虛擬Window
之所以說它是虛擬Window,而非Dialog,理由如下:
- 🚀 它裡面裝的是獨立的Page而非Fragment,僅根據Url就可以重建彈窗,例如//admin-react-antd.eluxjs.com/admin/member/item/edit/50?__c=_dialog
- 🚀 它裡面裝的Page,不僅有獨立的Dom結構,還有獨立的
全局Store,類似於實現與外界隔離的運行環境。 - 🚀 它自帶獨立的歷史記錄棧,基於它的每一個路由跳轉都將自動形成一條歷史記錄。
- 🚀 它提供類似瀏覽器窗口的工具條:關閉/後退/刷新。如:文章列表 => 點擊標題 => 點擊作者 => 點擊文章數。然後你可以依次回退每一步操作,也可一次性全部關閉。
- 🚀 它提供窗口最大化、最小化按鈕,如:文章詳情,窗口左上角按鈕;並支援默認最大化,如:創建文章
- 🚀 只需一句話即可打開新窗口,例如
- 🚀 Window中可以再開新窗口,最多可達10級,自動維護層級關係。
- 🚀 彈窗再彈彈窗體驗不好?多層彈窗時自動隱藏下層彈窗,關閉上層彈窗自動恢復下層彈窗,保證每一時刻始終之會出現一層彈窗。
- 🚀 輕鬆實現是否keep-alive。
keep-alive優點是用戶體驗好,缺點是太TM佔資源(需要快取所有Dom元素還有相關記憶體變數),現在使用虛擬Windw,你想keep-alive你就在新窗口中打開,不想keep-alive就在原窗口中打開,隨意控制。
項目地址
虛擬Window也算是摸著石頭過河,大家有什麼意見、想法、改進思路,都歡迎提供哦...
最後附上項目地址:
- React版本
- Vue版本
