日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

富交互Web应用中的撤销和前进

發布時間:2025/3/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 富交互Web应用中的撤销和前进 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在web應用中,用戶在進行一些富交互行為的操作時難免會出現誤操作,比如在富文本編輯器設置錯了字體顏色就需要撤回,做H5活動頁面的時候不小心刪了一個圖片也需要撤回,更比如在線設計原型圖應用的時候不小心刪了一個頁面等,總之在交互場景非常復雜的情況下,用戶操作失誤的可能性非常大,這時候‘撤銷’和‘前進’這兩個操作就很有必要了,而且用戶體驗也很好

思路

不管是任何場景下的web應用,用戶的每一次操作我們都可以看成是對某個組件或某個對象的狀態和屬性進行改變,一旦連續的動作操作完成正準備進行下一個動作之前,此刻的狀態就是一個全新的狀態

A —— B —— C
用戶未操作的時候全局狀態是A
用戶操作某個組件使其移動到位置X,松開鼠標之后全局狀態是B
用戶操作另一個組件使其刪除,完成后全局狀態是C

所以,撤銷的操作就是在用戶操作狀態到C的時候讓全局的狀態回到B,回到上一次操作完的時候。
那么就需要可以存放這種大量狀態的列表或索引來記錄每一次操作的動作

但如果我用某一個數組變量來存儲如此龐大的數據是不是略顯不妥?數據量越大內存應該會爆吧?所以這里我推薦大家使用IndexedDB
下面是利用Angular、Rxjs和IndexedDB封裝好的一個服務類

import { Inject } from "@angular/core"; import { IndexedDBAngular } from "indexeddb-angular"; import { Subject, Observer, Observable } from "rxjs";export interface IDBData {widgetList: string }// 前進和后退的服務 @Inject({providedIn: 'root' }) export class PanelExtendMoveBackService {/*** 發射DB集合存儲的數據,可訂閱*/public launchDBDataValue$: Subject<IDBData> = new Subject<IDBData>()/*** 創建一個叫panelDataDB的本地數據庫,版本號為1*/public db = new IndexedDBAngular('panelDataDB', 1)/*** 記錄前進和后退的存儲集合項的下標key* 默認為0*/public dbCurrentIndex: number = 0/*** 自增的DBkey*/public dbKey: number = -1// 是否允許前進public get isMove() : boolean {return this.dbCurrentIndex < this.dbKey}// 是否允許后退public get isBack() : boolean {return this.dbCurrentIndex > 0}constructor() {}/*** 創建DB集合*/public createCollections(): Observable<boolean> {const _sub: Subject<boolean> = new Subject<boolean>()this.dbKey = -1this.db.createStore(1, (db: any) => {db.currentTarget.result.createObjectStore('panelItem')}).then(()=>{this.dbClear()_sub.next(true)})return _sub.asObservable()}/*** 往集合里添加數據* 同時把新添加的key賦值給dbCurrentIndex,*/public dbAdd(): void {this.handleDbCurrentRefreshDB();this.dbKey += 1;// 此處存儲你要保存的數據const _widget_list = []this.db.add('panelItem', { widgetList: JSON.stringify(_widget_list) }, this.dbKey).then(_e => {if ((<Object>_e).hasOwnProperty('key')) {this.dbCurrentIndex = _e.key};},() => {this.dbKey -= 1throw new Error('添加panelItem集合失敗')})}/*** 在執行添加數據集操作的時候判斷dbCurrentIndex當前指引的下標是否低于dbKey* 如果是說明執行了后退操作之后后續動作執行了dbAdd的操作,則清空dbCurrentIndex索引之后的數據重新添加*/public handleDbCurrentRefreshDB(): void {if (this.dbCurrentIndex < this.dbKey) {for (let i = this.dbCurrentIndex + 1; i <= this.dbKey; i++) {this.db.delete('panelItem', i).then(() => {})}this.dbKey = this.dbCurrentIndex}}/*** 執行后退操作發射DB數據集*/public acquireBackDBData(): void {if( this.isBack ) {this.dbCurrentIndex -= 1this.db.getByKey('panelItem', this.dbCurrentIndex).then(res=>{this.launchDBDataValue$.next(res)},()=>{ })}}/*** 執行前進操作發射DB數據集*/public acquireMoveDBData(): void {if( this.isMove ) {this.dbCurrentIndex += 1this.db.getByKey('panelItem', this.dbCurrentIndex).then(res => {this.launchDBDataValue$.next(res)}, () => { })}}/*** 清除DB集合panelItem*/public dbClear(): void {this.db.clear('panelItem').then(_e => {})} }

這里我偷懶了一下,直接采用自增的id作為key了,也方便查找
每一次操作所存儲的數據如下

最后可以看一下我實現好了的撤銷和前進操作的場景

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的富交互Web应用中的撤销和前进的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。