JS - 步驟紀錄器實作

前言

昨天有人問了一題有趣的題目,內容是問要怎麼實作編輯器得上一步下一步動作,也是就是說要做一個步驟紀錄器,覺得沒做過這種東西覺得好像蠻有趣的, 就來試試看。

步驟紀錄器原理

基本原理

原理很簡單,先建立一個Array當作容器,每次輸入時使用就把資料塞進Array中,在使用一個變數紀錄當前的步驟,上一步就是把資料還原上一個Array元素的內容而已,是不是很簡單呢?XD

紀錄的頻率

HTML的DOM事件只能監控你每次輸入的瞬間,假如說你輸入123,這樣會產生3步,這樣感覺紀錄的太細膩,所以我們要做一個延遲,需要輸入後停止多久的時間,紀錄器才會把資料記錄下來。

紀錄器的空間控管

當然紀錄器的空間要有限制,不是一直Array.push()就好,這樣你會害使用者記憶體爆掉的….

所以我們一定要限制Array的大小,對使用者來說就是可以紀錄的幾個步驟。

步驟紀錄器實作

建立基本容器與變數

實作使用TextArea來當示範,首先先建立2個ButtonTextArray

1
2
3
<button id="prev" type="button">上一步</button>
<button id="next" type="button">下一步</button>
<textarea id="text" cols="5"></textarea>

建立Array和使用的變數

1
2
3
4
5
var step = 0; // 步驟變數
var textList = new Array(); // array容器
var prev = document.getElementById('prev');
var next = document.getElementById('next');
var text = document.getElementById('text');

步驟事件建立及加入輸入的監聽

寫一個事件,每個步驟都會把TextArea的內容寫入textList,並寫步驟+1

1
2
3
4
function textWrite(){
    step++; 
    textList.push(text.value);
}

當然只有事件是不會自動執行的,此時我們需要監控TextArea的輸入,並執行上面的事件

1
text.addEventListener('input', textWrite);

上下步事件建立

這邊開始就簡單了,上一步只要讀取上個Array元素的資料並塞進TextArea,下一步則是倒過來。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
prev.onClick = function(){
    // 判斷是否還有上一步
    if(step < 2){
        alert('沒有上一步');
    }else{
        step--;// 步驟往回一步
        text.value = textList[step - 1]; // 因為Array從0開始所以要-1
    }
}

next.onClick = function(){
    if(step => textList.length){
        alert('沒有下一步');
    }else{
        step++;
        text.value = textList[step - 1];
    }
}

Demo



延遲紀錄的實現

這個就要使用我的上一篇文章,使用Lodash的_.debounce就能實現了。

1
2
var debounce = _.debounce(textWrite, 500);// 延遲500毫秒紀錄
text.addEventListener('input', debounce);// 改成監聽延遲函數

Demo2



步驟器的限制

要限制很簡單,只要儲存容器本身要限制寬度就行,這邊主要的另一個問題應該是超出範圍是該怎麼辦? 答案很簡單就是把現有資料向前移動就行,然後在最後一項資料再塞進新資料。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var textList = new Array(3); // 限制Array只能4個元素
function textWrite(){
    // 判斷是否已到最大紀錄步驟
    if(step === textList.length){
        for(var i = 0;i < textList.length - 1; i++){
            textList[i] = textList[i + 1];
        }
        textList[step - 1] = text.value; 
    } else {
        step++; 
        textList[step] = text.value;
    }
}

Demo3



後記

整體來說不難,最後一項步驟器的限制難度有比較高,我在想資料位移時還一直想到腦筋打結,原本是for遞減,後來想一想好像遞增比較好寫, 害我卡了很久,不過很多IT邦很多大大說編輯器很難寫是真的,雖然基本的觀念不是很難,但是細部的微調真的很難寫,例如我其時還少寫了一個步驟不在最後一步時, 要覆寫後面的步驟,實作起來應該是更難,我這邊就不做了(暈)。

comments powered by Disqus
使用 Hugo 建立
主題 StackJimmy 設計