今天阿里巴巴的面試官打來電話,問了一個問題,大概內容如下?

問題大概是:做一個保存草稿的頁面,每隔十分鐘會自動保存一次,如果在多個頁面中打開了同一頁面,怎樣確保往資料庫里存的是用戶想要保存的內容。

求大神解決這個問題。


需求有問題,草稿應該是變更時立刻做保存。這樣你開多少頁面都能確保你存的是你最後想要的,因為用戶編輯了。

我做過這種需求,遇到這樣的產品我心裡很捉急…


每個頁面的文檔發生改變的時候都往同一個localStorage值寫入備份,互相覆蓋。

向伺服器備份的時候只備份localStorage里這個唯一的備份即可。


前天在實現自己一個項目的後台Admin界面的時候剛好碰到了這個需求。

我自己的解決方案是檢測

document.visibilityState

僅當值為「visible」時才保存。

這個值只有你在看著這個頁面的時候才為「visible」。一般情況下認為用戶看著的頁面就是他正在活動的頁面就沒有問題了。

(實現的時候注意瀏覽器兼容性)

但是這樣會帶來另一個問題,就是我自己在寫長篇大論的時候,習慣開很多頁面來看資料,也許大部分時間我在看資料,這樣就可能哪個頁面都沒保存上。

我結合自己的使用習慣最後做出的實現是,檢測visibilitychange事件,在頁面從「visible」變為其他狀態時運行一下保存草稿。然後重定義了Ctrl+S快捷鍵,作用是保存草稿。

這種實現對於我自己的需求來說已經足夠了。

還有一種可能的實現是,多個頁面之間可以用localStroage或者類似的方式共享值,這樣就可以實現更加複雜的頁面間通信。可以設計一套規則,讓最後用戶編輯活動的頁面拿到一個Token,然後自動保存的時候只有有Token才可以保存。

不過如果開多個相同頁面編輯不是常態,這樣有點小題大做了。


這個問題的分類是前端開發,那麼以被提問者是前端的情況來回答這個問題。

首先:這個需求不明確,且此問題應該是產品經理去考慮的,不應該丟給前端解決。

---------------------------------------------------------

如果遇到這種坑的時候,前端應該向產品經理提出『技術建議』和『解決方案』,讓產品經理明確需求。千萬不要前端擅自決定並執行。

其他答案已經給出了一些技術建議和解決方案。

比如:

1. 草稿應該是變更時立刻做保存。這樣你開多少頁面都能確保你存的是你最後想要的,因為用戶編輯了 @小爝

2. 多個頁面中某個頁面修改後, 同步到其他頁面, 或者作出提示 @匿名用戶

需求不明確的情況下即使**給出具體的技術方案都無法解決問題**。只有先幫助產品經理明確需求,然後與後端溝通商量出實現方案才能解決問題。


這個可以參考一下樂觀鎖。

有草稿肯定就有讀取草稿和保存草稿的功能。草稿表有內容欄位和version欄位。

開多個頁面,每個頁面都讀取草稿,此時有相同的內容和version。

某個頁面上內容變了,提交草稿,提交成功version會變,本地也會同步version欄位。

其他的頁面上的草稿如果再保存,version值就低了,不被伺服器接受,這時候可以給用戶一個提示什麼的,然後把本地的內容更新成伺服器最新的草稿,本地的version欄位也更新成最新的,就可以保存了。

另外本地保存時間戳是不行的,無法避免草稿被覆蓋,因為舊的數據可以後提交。所以version必須是保存在資料庫表裡的欄位。

不知道題主有沒有看明白。


多個頁面都在一台電腦上么,會不會在不同的電腦上打開多個同一頁面?

雖然在同一個電腦上,但是頁面會不會被打開在不同的瀏覽器里?

所以我覺得,後台應該給每一次存儲做一個編碼(無論是編輯中的自動保存還是最終的保存結果),每一次前端激活頁面以及自動保存的時候都應該去比對自己的數據編碼是不是還和後台當前數據編碼一致,如果不一致,跳出個窗口給用戶說下好了,或者像svn里搞個diff,讓用戶自己決定取捨


window postMessage API [Cross-window messaging with postMessage]

HTML5 Web Storage [HTML5 Web Storage and Cross-tab communication]

Broadcast Channel API [Broadcast Channel API]


死腦筋,這種情況下應該找產品經理商量出一個合理規則,然後找UI設計一個好看的界面,提示用戶這樣會出亂子。


監聽編輯框的onchange事件, 動態把修改後的內容保存到變數裡面,比如

var needSave= {
timestamp:changetime, //修改時間
contents:newcontens //修改後的內容
};

然後定時保存的時候先檢測neddSave["timestamp"]是否大於上一次保存的時間戳


如果存在用戶在多個頁面保存不同信息,還都是想要保存的信息的話你怎麼搞?定時器然後所有頁面自動刷新?修改操作的時候其他頁面同步刷新?

如果不是上面你這種情況的話,那就用locakStorage咯,所有頁面之間利用localStorage共享時間信息,根據最後修改的時間調整頁面信息的優先順序,我的想法簡單來說就是這樣。

我覺得知乎這種辦法就聽好了,來個提示就好了。


看過石墨文檔吧 感覺應該和那個差不多


看到很多人監聽 document.visibilityState,但是它的兼容性實在太差,我來提一個方法,至少可以兼容到ie7。

總體是這樣:

1 、進入頁面用戶編輯前恢復一次草稿。

2、用戶最後編輯的就是他想要的。

3、自定義一個方法判斷用戶離開、進入頁面。

4、離開頁面或者10分鐘到,並且內容被編輯過時存草稿

判斷頁面離開、進入:

html標籤監聽mouseenter事件,處理用戶返回頁面,mouseleave事件配合cookie 處理離開 ,cookie有效時間為空。 當用戶不離開頁面而是點擊了瀏覽器的菜單欄等地方時mouseleave mouseenter也會觸發,但是用戶並沒有真正的離開又返回頁面。

判斷內容有沒有被修改:跟伺服器通信用ajax post json,取的草稿跟要發送的草稿做json字元串比對。

完整的流程如下: 打開頁面時:讀取草稿、使用時間戳+隨機數作為pageid。 mouseleave時:往伺服器存草稿、往cookie寫入pageid。 mouseenter時:讀cookie中的pageid,如果跟自己的pageid不一樣但是又不為空,就去伺服器取草稿,這個時候先用一個遮罩層凍住頁面,等一兩秒鐘以後再去取數據,防止用戶切換過快,數據沒有上傳完你就去取數據了。我被這種延時坑過。或者上傳成功後在cookie里設置一個標誌,確定要讀數據前輪詢它,取完就把標誌刪了。


能不能不裝逼,這明明是產品應該做的事情,別TM以為是大公司就可以無限裝逼,不齒下流。


需求簡單來說就是在十分鐘內,如果有兩次提交至伺服器則說明是衝突了,這個時候只需要看最後編輯時間,是伺服器中上一次提交的編輯時間新,還是這次要提交的新,然後留下那個新的就行了。

這樣答的話,這個題目就完全和前端沒有關係了。。。。。。。


其實這個問題很簡單,看似是保存,其實就是理解為協同工作。

goodow/realtime-store · GitHub

之前用過這個玩意,可供參考,有代碼 有思路。


focus的時候,記錄一個時間戳 記錄到一個ls變數 窗口名:時間戳;

每個頁面開啟定時器,記錄到另外一個ls變數 ,覆蓋之前窗口名對應的值, 窗口名:內容;

然後比較把最新時間戳對應的窗口名的內容存到資料庫。

窗口名可以用隨機字元串生成,保證唯一即可。


誰最後編輯就保存誰啊

每個頁面都實時或者修改時檢查一致性, 多個頁面中某個頁面修改後, 同步到其他頁面, 或者作出提示.


用pub sub模式,比如Meteor


我是這麼想的,我就大概說一下思路

如果是純前端來處理。只在保存數據時發送數據到後端可以這樣,

1 頁面是後端生成,例如你打開一個頁面這個頁面是伺服器端發送給瀏覽器,再頁面中生成一些標記,來標識這個頁面。

2 前端構件一個映射表(hash),或者叫map,既然打開多個頁面用時間戳來作為key或者別的,hash的value就是要保存的內容,

3 這樣map里就很多鍵值對,就是很多頁面,頁面內容有改動,就把其他的key對應的value也同步全變成一樣的。

4 這樣鍵值對里的值就都是一樣的了,但是存在一個問題。到底那個頁面是用戶想要的,

會不會用戶,打開了新的。忘記了以前的開過,或者新的和舊的都像要,

5 我打開一個頁面寫了1 ,再打開一個頁面寫了2 ,程序沒法判斷用戶想要1還是2,估計也就是要最後保存的,如果是想要最後保存的。

6其實可以再打開第二個的時候提示一下,已經打開了,這樣我覺得體驗比較好


推薦閱讀:

OOCSS、 SMACSS、 BEM、MVCSS你們在用哪個作基礎?
現在前端市場是不是已經飽和了?
怎樣才是優秀的前端工程師?
請問下93年的我,現在學編程晚嗎?
前端工程師有哪些靠譜的求職途徑?

TAG:前端開發 | 前端工程師 |