自己寫的"撤消/恢復"算法

自己寫的一個有限撤消/恢復算法。並用文本框進行了測試。

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Undo Redo</title>
<script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>

<style type="text/css">
body{margin:0;padding:0;font-family:Microsoft YaHei;}
.click{width:80px;height:20px;line-height:20px;margin-left:10px;float:left;text-align:center;border:#bbb solid 1px;background-color:#f5f5f5;cursor:pointer;}
</style>
</head>

<body>
<br/><br/><br/>
<div style='width:400px;height:400px;margin:0 auto;'>
<input type="text" id="itext" maxlength='2' style='width:76px;float:left;'>
<div id="do" class='click'>do</div>
<div id="undo" class='click'>undo</div>
<div id="redo" class='click'>redo</div>
<br/><br/><br/>
<div id='debug' style='clear:both;'></div>
<br/><br/>
<div id='prevnow' style='clear:both;width:400px;height:20px;line-height:20px;text-align:center;font-size:14px;'></div>

<br/><br/>
<textarea id='tt' maxlength='100' style='width:390px;height:100px;'></textarea>
<div style='width:400px;font-size:14px;color:#e00;text-align:center;'>(*限字母和數字,漢字無法觸發keyup)</div>

<div style='width:400px;height:20px;margin-top:20px;margin-left:200px;'>
<div id="tundo" class='click'>undo</div>
<div id="tredo" class='click'>redo</div>
</div>

<br/>
<div id='debug2' style='width:400px;height:100px;display:none;'></div>

</div>



<script language="javascript">
var ud = new UndoRedo(10);
var ud2 = new UndoRedo(100);

for(var i=1;i<=10;++i){
ud.do(i+"");
}


$("#debug").append(ud.debug());
var now = ud.now();
now = now == null ? "無" : now;
var prev = ud.prev();
prev = prev == null ? "無" : prev;
$("#prevnow").text("當前數據:"+now+",上一個數據:"+prev);


$(".click").each(function(){
    $(this).click(function(){
        switch($(this).prop("id")){
        case "do":
        var t = $("#itext").val();
        if(t != null && t != undefined && t.length > 0){
            ud.do(t);
            $("#debug").empty();
            $("#debug").append(ud.debug());
            
            var now = ud.now();
            now = now == null ? "無" : now;
            var prev = ud.prev();
            prev = prev == null ? "無" : prev;
            $("#prevnow").text("當前數據:"+now+",上一個數據:"+prev);
        }
        break;
        case "undo":
        var t = ud.undo();
        if(t != null && t != undefined){
        
            $("#debug").empty();
            $("#debug").append(ud.debug());
            
            var now = ud.now();
            now = now == null ? "無" : now;
            var prev = ud.prev();
            prev = prev == null ? "無" : prev;
            $("#prevnow").text("當前數據:"+now+",上一個數據:"+prev);
        }

        break;
        case "redo":
        var t = ud.redo();
        if(t != null && t != undefined){
            
            $("#debug").empty();
            $("#debug").append(ud.debug());
            
            var now = ud.now();
            now = now == null ? "無" : now;
            var prev = ud.prev();
            prev = prev == null ? "無" : prev;
            $("#prevnow").text("當前數據:"+now+",上一個數據:"+prev);
        }
        
        break;
        
        case "tundo":
        var t = ud2.undo();
        if(t != null){
            $("#tt").val(t);
        }
        
        $("#debug2").empty();
        $("#debug2").append(ud2.debug());
        break;
        
        case "tredo":
        var t = ud2.redo();
        if(t != null){
            $("#tt").val(t);
        }
        
        $("#debug2").empty();
        $("#debug2").append(ud2.debug());
        break;
        }
    });
});


$("document").ready(function(){
    
    $("#itext")[0].value = "";
    $("#tt")[0].value = "";
    
    ud2.do("");
    $("#debug2").empty();
    $("#debug2").append(ud2.debug());

    $("#tt").keyup(function(){
      var t = $("#tt").val();
      if(t != null && t != undefined){
          ud2.do(t);
          
          $("#debug2").empty();
          $("#debug2").append(ud2.debug());
      }
      
    });
});


function UndoRedo(size)
{
    var s = size;
    var l = 0;//obj count
    var pos = -1;//current data
    
    var a = new Array(l);

    for(var i=0;i<s;++i){
        a[i] = null;
    }
    
    this.do = function(obj)
    {
        if(pos == l-1){//指針在數據未尾
        
            if(l == s){//如數組已滿則清除掉最舊的數據
                for(var i=0;i<s-1;++i){
                    a[i] = a[i+1];
                }
                a[s-1] = obj;
            }
            else{
                a[pos+1] = obj;
                pos +=1;
                l++;
            }
        }
        else{//指針不在數據未尾

            if(pos >= 0){
                a[pos+1] = obj;
                for(var i=pos+2;i<s;++i){
                    a[i] = null;
                }
                l = pos + 2;
                pos+=1;
            }
            else{
                a[0] = obj;
                l=1;
                pos = 0;
            }
        }
    }
    
    //返回上一個數據,但不移動標誌
    this.prev = function()
    {
        if(pos > 0){
            return a[pos-1];
        }
        return null;
    }
    
    //返回當前數據
    this.now = function()
    {
        if(pos >=0 && pos < l){
            return a[pos];
        }
        return null;
    }
    
    //返回上一個數據
    this.undo = function(state)
    {
        if(state == true){
            return pos > 0 ? true : false;
        }
        else{
            if(pos > 0){
                var re = a[pos-1];
                pos-= 1;
                return re;
            }
            else{
                return null;
            }
        }
    }
    
    //返回下一個數據
    this.redo = function(state)
    {
        if(state == true){
            return (pos < l-1) ? true : false;
        }
        else{
            if(l > 0){
                if(pos < l-1){
                    var obj = a[pos + 1];
                    pos += 1;
                    return obj;            
                }
                else{
                    return null;
                }
            }
            else{
                return null;
            }
        }
    }
    
    //測試用
    this.debug = function()
    {
        var temp="<div>";
        
        for(var i=0;i<s;++i){
            temp+="<div style='width:30px;height:20px;line-height:20px;float:left;text-align:center;background-color:#f00;margin:2px;color:#fff;'></div>";
        }
        temp +="</div>";
        
        var o = $(temp);

        for(var i=0;i<l;++i){
            o.children().eq(i).css("background-color","#00f");
            o.children().eq(i).text(a[i]);
        }
        
        if(pos >= 0){
            o.children().eq(pos).css("color","#f00");
        }
        
        return o;
    }
}
</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章