欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript前端實(shí)現(xiàn)快照的示例代碼

 更新時(shí)間:2023年11月14日 17:01:46   作者:小丸子不好吃  
snapshot 翻譯為快照,用于直觀獲取頁(yè)面在某個(gè)運(yùn)行時(shí)的狀態(tài),本文主要為大家詳細(xì)介紹 snapshot 工具實(shí)現(xiàn)的原理,以及其在項(xiàng)目中的使用,需要的可以參考下

簡(jiǎn)介

snapshot 翻譯為快照,用于直觀獲取頁(yè)面在某個(gè)運(yùn)行時(shí)的狀態(tài),將執(zhí)行操作前后的快照進(jìn)行存儲(chǔ),可以輕松實(shí)現(xiàn)頁(yè)面狀態(tài)的重做、撤銷功能。

本文主要介紹 snapshot 工具實(shí)現(xiàn)的原理,以及其在項(xiàng)目中的使用。

設(shè)計(jì)

要實(shí)現(xiàn)頁(yè)面狀態(tài)的歷史記錄、重做、撤銷,需要支持以下幾個(gè)屬性和方法

屬性

  • 歷史記錄:存儲(chǔ)歷史的頁(yè)面狀態(tài),包含頁(yè)面初始化的狀態(tài) 到 上一個(gè)頁(yè)面狀態(tài)
  • 撤銷記錄:存儲(chǔ)重做的每一個(gè)操作記錄,用于撤銷后恢復(fù)
  • 當(dāng)前記錄:臨時(shí)存儲(chǔ)當(dāng)前頁(yè)面狀態(tài),主要用于下一次操作后,需要將其存儲(chǔ)到歷史記錄
  • 上次插入數(shù)據(jù)時(shí)間:插入時(shí)間間隔太小時(shí),需要額外處理
 // 歷史記錄
 recordList: string[] = []
 ?
 // 撤銷記錄,用于重做
 redoList: string[] = []
 ?
 // 當(dāng)前記錄用 currentRecord 變量暫時(shí)存儲(chǔ),當(dāng)用戶修改時(shí),再存放到 recordList
 currentRecord = ''
 ?
 // 上次插入數(shù)據(jù)時(shí)間
 time = 0

方法

存儲(chǔ)歷史記錄 push

當(dāng)用戶操作后,更新歷史記錄。需要考慮以下幾點(diǎn)。

  • 當(dāng)前操作時(shí)間距離上次插入時(shí)間小于 100 ms 時(shí),則替換當(dāng)前記錄并取消執(zhí)行添加
  • 如果當(dāng)前記錄有值,則說(shuō)明上一次操作是手動(dòng)插入,將之前緩存的當(dāng)前記錄推入 recordList,并且需要清空重做記錄
  • 將當(dāng)前狀態(tài)存儲(chǔ)到當(dāng)前記錄
  • 設(shè)置最大歷史記錄容量,當(dāng)超過(guò)時(shí),將最先插入的數(shù)據(jù)刪除
 push(record: PageData) {
   const nowTime = Date.now()
   // 防止添加重復(fù)的時(shí)間,當(dāng)添加間隔小于 100ms 時(shí),則替換當(dāng)前記錄并取消執(zhí)行添加
   if (this.time + 100 > nowTime) {
     try {
       // 將 json 轉(zhuǎn)成字符串存儲(chǔ)
       this.currentRecord = JSON.stringify(record)
     } catch (error) {
       return false
     }
 ?
     return false
   }
 ?
   this.time = nowTime
 ?
   // 判斷之前是否已經(jīng)存在currentRecord記錄,有則存儲(chǔ)到recordList
   if (this.currentRecord) {
     this.recordList.push(this.currentRecord)
     // 增加記錄后則應(yīng)該清空重做記錄
     this.redoList.splice(0, this.redoList.length)
   }
 ?
   // 存儲(chǔ)當(dāng)前記錄
   this.currentRecord = JSON.stringify(record)
 ?
   // 最多存儲(chǔ) 30 條記錄,超過(guò)則刪除之前的記錄
   if (this.recordList.length > 30) {
     this.recordList.unshift()
   }
   return true
 }

撤銷操作 undo

當(dāng)用戶操作后,依賴 push 時(shí)存儲(chǔ)的歷史記錄列表,將頁(yè)面狀態(tài)回退到上一次的狀態(tài),需要注意以下幾點(diǎn):

  • 當(dāng)歷史記錄沒(méi)有時(shí),直接返回
  • 從歷史記錄中取出最后一次存儲(chǔ)數(shù)據(jù)
  • 若當(dāng)前記錄存在,需要將其存放到重做記錄列表
  • 需要清空當(dāng)前記錄,防止重復(fù)添加,因?yàn)槌蜂N后,也會(huì)執(zhí)行 push 存儲(chǔ)歷史記錄方法
 undo() {
   // 沒(méi)有記錄時(shí),返回 false
   if (this.recordList.length === 0) {
     return null
   }
 ?
   const record = this.recordList.pop()
 ?
   // 將當(dāng)前記錄添加到重做記錄里面
   if (this.currentRecord) {
     this.redoList.push(this.currentRecord)
   }
 ?
   // 丟棄當(dāng)前記錄,防止重復(fù)添加
   this.currentRecord = ''
   return JSON.parse(record as string) as PageData
 }

重做操作 redo

當(dāng)用戶操作后,依賴 redoList 列表,將頁(yè)面狀態(tài)回退到撤銷前的狀態(tài),需要注意以下幾點(diǎn):

  • 當(dāng)重做記錄沒(méi)有時(shí),直接返回
  • 從重做記錄里取出最后一次存儲(chǔ)數(shù)據(jù)
  • 如果當(dāng)前記錄有值,需要將其放到歷史記錄列表
  • 需要清空當(dāng)前記錄,防止重復(fù)添加,因?yàn)橹刈龊?,也?huì)執(zhí)行 push 存儲(chǔ)歷史記錄方法
 redo() {
   // 沒(méi)有重做記錄時(shí),返回 false
   if (this.redoList.length === 0) {
     return null
   }
 ?
   const record = this.redoList.pop()
   // 添加到重做記錄里面
   if (this.currentRecord) {
     this.recordList.push(this.currentRecord)
   }
 ?
   // 丟棄當(dāng)前記錄,防止重復(fù)添加
   this.currentRecord = ''
   return JSON.parse(record as string) as PageData
 }

過(guò)程演示

假設(shè)數(shù)據(jù)列表為 [1, 2, 3, 4],當(dāng)前屬性值分別為:

 recordList = [1, 2, 3]
 redoList = []
 currentRecord = 4

1、手動(dòng)添加 5,則會(huì)執(zhí)行 push 方法,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3, 4]
 redoList = []
 currentRecord = 5

2、執(zhí)行1次撤銷,則先會(huì)執(zhí)行 undo,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3]
 redoList = [5]
 currentRecord = ''

然后執(zhí)行 push,將 4 push 進(jìn)去,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3]
 redoList = [5]
 currentRecord = 4

3、執(zhí)行第2次撤銷,則先會(huì)執(zhí)行 undo,執(zhí)行后屬性值分別為

 recordList = [1, 2]
 redoList = [5, 4]
 currentRecord = ''

然后執(zhí)行 push,將 3 push 進(jìn)去,執(zhí)行后屬性值分別為

 recordList = [1, 2]
 redoList = [5, 4]
 currentRecord = 3

4、執(zhí)行1次重做,則先會(huì)執(zhí)行 redo,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3]
 redoList = [5]
 currentRecord = ''

然后執(zhí)行 push,將 4 push 進(jìn)去,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3]
 redoList = [5]
 currentRecord = 4

5、手動(dòng)添加 6,則會(huì)執(zhí)行 push 方法,執(zhí)行后屬性值分別為

 recordList = [1, 2, 3, 4]
 redoList = []
 currentRecord = 6

完整代碼

 export default class Snapshot {
     // 歷史記錄
     recordList: string[] = []
 ?
     // 撤銷記錄,用于重做
     redoList: string[] = []
 ?
     // 當(dāng)前記錄用 currentRecord 變量暫時(shí)存儲(chǔ),當(dāng)用戶修改時(shí),再存放到 recordList
     currentRecord = ''
 ?
     // 上次插入數(shù)據(jù)時(shí)間
     time = 0
 ?
     push(record: PageData) {
         const nowTime = Date.now()
         // 防止添加重復(fù)的時(shí)間,當(dāng)添加間隔小于 100ms 時(shí),則替換當(dāng)前記錄并取消執(zhí)行添加
         if (this.time + 100 > nowTime) {
             try {
                 // 將 json 轉(zhuǎn)成字符串存儲(chǔ)
                 this.currentRecord = JSON.stringify(record)
             } catch (error) {
                 return false
             }
 ?
             return false
         }
 ?
         this.time = nowTime
 ?
         // 判斷之前是否已經(jīng)存在currentRecord記錄,有則存儲(chǔ)到recordList
         if (this.currentRecord) {
             this.recordList.push(this.currentRecord)
             // 增加記錄后則應(yīng)該清空重做記錄
             this.redoList.splice(0, this.redoList.length)
         }
 ?
         try {
             // 將 json 轉(zhuǎn)成字符串存儲(chǔ)
             this.currentRecord = JSON.stringify(record)
         } catch (error) {
             return
         }
 ?
         // 最多存儲(chǔ) 30 條記錄,超過(guò)則刪除之前的記錄
         if (this.recordList.length > 30) {
             this.recordList.unshift()
         }
         return true
     }
 ?
     undo() {
         // 沒(méi)有記錄時(shí),返回 false
         if (this.recordList.length === 0) {
             return null
         }
 ?
         const record = this.recordList.pop()
 ?
         // 將當(dāng)前記錄添加到重做記錄里面
         if (this.currentRecord) {
             this.redoList.push(this.currentRecord)
         }
 ?
         // 丟棄當(dāng)前記錄,防止重復(fù)添加
         this.currentRecord = ''
         return JSON.parse(record as string) as PageData
     }
 ?
     redo() {
         // 沒(méi)有重做記錄時(shí),返回 false
         if (this.redoList.length === 0) {
             return null
         }
 ?
         const record = this.redoList.pop()
         // 添加到重做記錄里面
         if (this.currentRecord) {
             this.recordList.push(this.currentRecord)
         }
 ?
         // 丟棄當(dāng)前記錄,防止重復(fù)添加
         this.currentRecord = ''
         return JSON.parse(record as string) as PageData
     }
 }

到此這篇關(guān)于JavaScript前端實(shí)現(xiàn)快照的示例代碼的文章就介紹到這了,更多相關(guān)JavaScript快照內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論