JS 实现撤销与反撤销 (ctrl+Z,ctrl+Y)

本文不是监听的键盘事件,进行撤销,,而是   多用于移动端开发,基于按钮实现对编辑框的撤销与反撤销。

写的并不完美,记录一下而已。

思路:将改变后的文本存入栈中,点击撤销时取出栈顶元素,替换文本框中内容同时放到另一个栈中为反撤销用

1.  stack 栈    先入后出原则 完美利用到本业务中

首先利用js内置对象 数组,建立栈对象

//栈
function ArrayStack(){
    var arr = [];  
        //压栈操作  
    this.push = function(element){  
        arr.push(element);  
    }  
        //退栈操作  
    this.pop = function(){  
        return arr.pop();  
    }  
        //获取栈顶元素  
    this.top = function(){  
        return arr[arr.length-1];  
    }  
        //获取栈长  
    this.size = function(){  
        return arr.length;  
    }  
        //清空栈  
    this.clear = function(){  
        arr = [];  
        return true;  
    }  
  
    this.toString = function(){  
        return arr.toString();  
    }  
} 

2.建立栈对象,监听文本框改变事件

	var stackZ = new ArrayStack();
	var stackY = new ArrayStack();


	document.getElementById('text').addEventListener("input",function(){
		setTimeout(function(){
			if(isInputZh){
			return;
		}
		var t = text.val();
		var ht = $('#hiText').val();
	//	console.log(ht)				//TODO
		if(ht){
			stackZ.push(ht);
			$('#hiText').val(t);
		}else{
			$('#hiText').val(t);
		}
		},0)
		});

这里新建了一个隐藏域,用于存放当前文本框中的值,避免第一次点击撤销时还是文本中框的内容

 

这里有一个小tIps:当一个文本框输入中文时,拼音会先写入到文本中,然后替换为中文,这样拼音也记录到栈中了,这是不想要的,网上找了别的方法,利用两个事件做开关,屏蔽掉拼音这一段

	//输入框输入文字  oninput事件不记录拼音
	document.getElementById('text').addEventListener('compositionstart', function (e) {
	  isInputZh = true;
	}, false);
	document.getElementById('text').addEventListener('compositionend', function (e) {
 	 isInputZh = false;
	}, false);

3. 方法ctrlZ,方法ctrlY

	//ctrl + z
	function ctrlZ(){
		var p =stackZ.pop();
		if(p){
			text.val(p);
			stackY.push(p);
		}

	}
	//ctrl + y
	function ctrlY(){
		var p =stackY.pop();
	//	console.log("p:"+p)			//TODO
		if(p){
			if(p==text.val()){
				ctrlY();
			}else{
				text.val(p);
				stackZ.push(p);
			}
		}else{
			text.val($('#hiText').val());
		}
	}

这么low的代码,都能写出来,,

重点是利用栈来写,不是人人都能想到,特此记录。

要更好的方法   欢迎讨论

你可能感兴趣的:(JS 实现撤销与反撤销 (ctrl+Z,ctrl+Y))