2016-10-06 3 views
-3

私はTシャツのカスタム設計ソフトウェア・ツールを持って、私はここでhttp://mattjmattj.github.io/simple-undo/ブラウザでJavascriptでイベントを取り消してやり直すにはどうすればいいですか?

+0

ため、関数クロージャの、非常に簡単です、あなたが必要となるすべてはあなたが取り消し・やり直しスタックを保存して、あなたのDOさんをプッシュする配列であり、取り消しを配列に追加します。例えば。 undoredu.push({do:somedofunc()、undo:somundofunc()});私は最近このテクニックを使ってアニメーションを編集しました - > http://stackoverflow.com/questions/39885261/javascript-settimeout-closure-inside-nested-double-for-loops/39885404#39885404あなたが見ているならどんな混乱も私たちに知らせてください。 – Keith

+0

あなたは私にそれを行う方法を教えてもらえますか – Parker

+0

私は単純な例を打つことができますか? – Keith

答えて

1

プラグインアンドゥマネージャで試してみましたREDOを追加し、ドラッグ可能な

http://wordpress.tshirtecommerce.com/design-online/?product_id=17

あるテキストのためのイベントを元に戻す必要がありいます私たちはあります。 。

これは、元に戻す&やり直しバッファをやって、REDOを処理するために、関数クロージャを使用しての簡単な例..です

これはもちろん、非常に簡単な例ですので、あまりにも簡単ですが、このテクニックを使用して元に戻す/やり直すことはできません。何か、あなたは関数のクロージャに渡され、キャプチャされ、次に再生することができます。

var e = {}; //lets store references to the dom elemements 
 
Array.prototype.slice.call(document.querySelectorAll("[id]")). 
 
    forEach(function (el) { e[el.id] = el; }); 
 

 
var stack = [], 
 
    stackPos = 0, 
 
    names = []; 
 

 
function showNames() { 
 
    e.lbNames.textContent = names.join(', '); 
 
    e.btUndo.disabled = stackPos <= 0; 
 
    e.btRedo.disabled = stackPos >= stack.length; 
 
    e.lbBuffer.textContent = stack.length; 
 
} 
 

 
btAdd.onclick = function() { 
 
    if (!ipName.value) return alert("Please enter some text"); 
 
    //a function closure to capture the name 
 
    function add(name) { 
 
    return function() { 
 
     e.ipName.value = ''; 
 
     e.ipName.focus(); 
 
     names.push(name); 
 
     stackPos ++; 
 
     showNames(); 
 
    } 
 
    } 
 
    //no need for closure here, as were just going to pop the 
 
    //last one of the names, and shift the undo-pos back 
 
    function undo() { 
 
    stackPos --; 
 
    names.pop(); 
 
    showNames(); 
 
    } 
 
    //now lets add our do & undo proc 
 
    var doadd = add(ipName.value); 
 
    stack.splice(stackPos); 
 
    stack.push({ 
 
    do: doadd, 
 
    undo: undo 
 
    }); 
 
    //lets now do our inital do 
 
    doadd(); 
 
}; 
 

 
btUndo.onclick = function() { 
 
    var p = stack[stackPos - 1]; 
 
    p.undo(); 
 
}; 
 

 
btRedo.onclick = function() { 
 
    var p = stack[stackPos]; 
 
    p.do(); 
 
}; 
 

 
showNames();
<form onsubmit="return false"> 
 
    name: <input id="ipName"> 
 
    <br><br> 
 
    <button type="submit" id="btAdd" >Add</button> 
 
    <button id="btUndo">Undo</button> 
 
    <button id="btRedo">Redo</button> 
 
    Buffer = <span id="lbBuffer"></span> 
 
    <pre id="lbNames"></pre> 
 
</form>

0

[OK]を、私のオリジナルのポストについて私にやっかいた一つのことは、再利用性のものです。 Undo/Redoも実装の詳細に緊密に結びついていました。

私は再利用可能なクラスバージョンを作成しました。同時に、明確なオプションも追加しました。

オリジナルとこれを比較するのに便利だと思います。人々がコードを見て比較できるようにします。 JavaScriptで元に戻す/のReduシステムを行う

var e = {}; //lets store references to the dom elemements 
 
Array.prototype.slice.call(document.querySelectorAll("[id]")). 
 
    forEach(function (el) { e[el.id] = el; }); 
 

 

 
function UndoRedo(update_callback, clear_callback) { 
 
    this.update_callback = update_callback; 
 
    this.clear_callback = clear_callback; 
 
    this.clear(); 
 
} 
 

 
UndoRedo.prototype = { 
 
    
 
    clear: function() { 
 
    this.stack = []; 
 
    this.stackPos = 0; 
 
    if (this.clear_callback) this.clear_callback(); 
 
    this.update(); 
 
    }, 
 
    
 
    update: function() { 
 
    if (this.update_callback) this.update_callback(); 
 
    }, 
 
    
 
    canUndo: function() { 
 
    return this.stackPos > 0; 
 
    }, 
 

 
    canRedo: function() { 
 
    return this.stackPos < this.stack.length; 
 
    }, 
 

 
    doAction: function (doProc, undoProc) { 
 
    this.stack.splice(this.stackPos); 
 
    this.stack.push({ 
 
     do: doProc, 
 
     undo: undoProc 
 
    }); 
 
    this.stackPos ++; 
 
    doProc(); 
 
    this.update(); 
 
    }, 
 
    
 
    undo: function() { 
 
    var p = this.stack[this.stackPos - 1]; 
 
    this.stackPos --; 
 
    p.undo(); 
 
    this.update(); 
 
    }, 
 
    
 
    redo: function() { 
 
    var p = this.stack[this.stackPos]; 
 
    this.stackPos ++; 
 
    p.do();  
 
    this.update(); 
 
    } 
 
    
 
}; 
 

 

 

 
var  
 
    names = [], 
 
    undoRedo = new UndoRedo(
 
     function update() { 
 
     e.lbNames.textContent = names.join(', '); 
 
     e.btUndo.disabled = !this.canUndo(); 
 
     e.btRedo.disabled = !this.canRedo(); 
 
     e.lbBuffer.textContent = this.stack.length; 
 
     }, 
 
     function cleared() { 
 
     names = []; 
 
     } 
 
    ); 
 

 
btAdd.onclick = function() { 
 
    if (!ipName.value) return alert("Please enter some text"); 
 
    
 
    undoRedo.doAction(
 
    
 
    function add(name) { 
 
     return function() { 
 
     e.ipName.value = ''; 
 
     e.ipName.focus(); 
 
     names.push(name); 
 
     } 
 
    }(ipName.value), 
 
    
 
    function undo() { 
 
     names.pop(); 
 
    } 
 
    
 
); 
 
}; 
 

 
btUndo.onclick = function() { 
 
    undoRedo.undo(); 
 
}; 
 

 
btRedo.onclick = function() { 
 
    undoRedo.redo(); 
 
}; 
 

 
btClear.onclick = function() { 
 
    undoRedo.clear(); 
 
}
<form onsubmit="return false"> 
 
    name: <input id="ipName"> 
 
    <br><br> 
 
    <button type="submit" id="btAdd" >Add</button> 
 
    <button id="btUndo">Undo</button> 
 
    <button id="btRedo">Redo</button> 
 
    Buffer = <span id="lbBuffer"></span> 
 
    <button id="btClear">Clear</button> 
 
    <pre id="lbNames"></pre> 
 
</form>

関連する問題