07.01.2015, 01:30
|
Аспирант
|
|
Регистрация: 04.05.2011
Сообщений: 49
|
|
Сделать историю?
Доброй ночи! Мои мозги закипают уже
Имеется набор функций моего редактора, перед выполнением каждой фукции я сохраняю прошлый результат всего редактора в массив. Есть кнопка "Вернуть" при нажатии возвращается преведущий результат...
Дело в том что такой способ полностью работает, но так как я в массив заношу каждый раз огромный код сжатый код, хотелось бы ограничить "Возвращение" до 10 этапов
Как реализовано у меня:
Заход1:
Меняем данные в редакторе и пытаемся вернутся back(); => удивительно но работает сколько бы раз не возвращались (до 10)
Заход2:
Пытаемся после возвращений что-то изменить данные редактора и пытаемся вернутся back(); => не хочет возвращаться вообще
h_i = 1; // указал единицу так как в массиве первый ключ 1
history = [];
addhistory(); // Запускаю первый раз что бы добавить данные "как есть"
function addhistory() {
content = '';//тут я загоняю сгенерированный код редактором в JSON
if( history.length > 11 ) { // на 10 раз
h_i = 1;
history = [];
}
history.unshift(content);
}
function back() {
if( history.length > h_i ) { //смотрим что-бы хватало истории
readcontent( history[ h_i ] ); // возвращаем предыдущие данные
h_i++;
}
}
Последний раз редактировалось makar3000, 07.01.2015 в 01:46.
|
|
07.01.2015, 11:28
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от makar3000
|
if( history.length > 11 ) { // на 10 раз
h_i = 1;
history = [];
}
|
то есть ты каждый раз обнуляешь после 11 сохранений
копируй или смещай элементы массива вперед, в конец добавляй последний результат сохранения
|
|
07.01.2015, 14:37
|
Аспирант
|
|
Регистрация: 04.05.2011
Сообщений: 49
|
|
Делал вместо очистки .pop() все работало! Но если по второму кругу нажимать back() то в массиве были данные из первого круга и возвращалось то что было в первом круге а не во втором
|
|
07.01.2015, 15:22
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от makar3000
|
Делал вместо очистки .pop() все работало! Но если по второму кругу нажимать back() то в массиве были данные из первого круга и возвращалось то что было в первом круге а не во втором
|
<input>
<button>save</button>
<script>
document.querySelector("button").addEventListener("click", function () {
if (!this.mas) this.mas = [];
if (this.mas.length > 9) this.mas.shift();
this.mas.push(this.previousElementSibling.value);
console.log(this.mas);
});
</script>
|
|
07.01.2015, 17:15
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
опиши логику переходов по истории
<input>
<button class="save">save</button>
<button class="back">back</button>
<button class="forward">forward</button>
<script>
function addElement(element, mas, limit) {
if (mas.length > limit - 1) mas.shift();
mas.push(element);
}
document.querySelector(".save").addEventListener("click", function () {
var backBut = document.querySelector(".back");
delete backBut.n;
if (!this.mas) this.mas = [];
var input = document.querySelector("input");
addElement(input.value, this.mas, 10);
input.select();
console.log(this.mas);
});
document.querySelector(".back").addEventListener("click", function () {
var saveBut = document.querySelector(".save");
if (!saveBut.mas) saveBut.mas = [];
mas = saveBut.mas;
if (this.n == undefined) {
(!mas.length) ? this.n = 0 : this.n = mas.length - 1;
}
(this.n <= 0) ? this.n = 0 : this.n--;
document.querySelector("input").value = mas[this.n];
console.log("n=" + this.n + "; mas[n]=" + mas[this.n]);
});
</script>
|
|
07.01.2015, 17:51
|
Профессор
|
|
Регистрация: 12.04.2010
Сообщений: 557
|
|
Сообщение от bes
|
опиши логику переходов по истории
|
Обычно логика такая (если по уму делать):
есть массив (очередь), и есть указатель на текущий пункт в нем. Всё что перед указателем - "область повторов", прочее - "область отмен" (обе области могут быть пустые).
Функция undo - если есть команды в "области отмен", отменяем команду, на которой стоит указатель, перемещаем оный на шаг назад.
Функция redo - если есть команды в "области повторов", перемещаем указатель на шаг вперед и выполняем команду под ним.
Функция action (юзер хочет что-то сделать) - удаляем всё из "области повторов", формируем команду, ставим перед указателем, делаем redo. Если в очереди стало больше 10 элементов, удаляем самый старый.
Каждый элемент в очереди - команда, которую можно выполнить или отменить.
Последний раз редактировалось Яростный Меч, 07.01.2015 в 18:00.
|
|
07.01.2015, 18:46
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от Яростный Меч
|
Обычно логика такая (если по уму делать):
есть массив (очередь), и есть указатель на текущий пункт в нем. Всё что перед указателем - "область повторов", прочее - "область отмен" (обе области могут быть пустые).
Функция undo - если есть команды в "области отмен", отменяем команду, на которой стоит указатель, перемещаем оный на шаг назад.
Функция redo - если есть команды в "области повторов", перемещаем указатель на шаг вперед и выполняем команду под ним.
Функция action (юзер хочет что-то сделать) - удаляем всё из "области повторов", формируем команду, ставим перед указателем, делаем redo. Если в очереди стало больше 10 элементов, удаляем самый старый.
Каждый элемент в очереди - команда, которую можно выполнить или отменить.
|
отобрази на мой пример с тремя кнопками
save - action - удаляем все предыдущие элементы массива перед текущим, добавляем элемент в конец массива
back - undo - переходим на предыдущий элемент массива, если он есть
forward - redo - переходим на последующий элемент массива, если он есть
так?
|
|
07.01.2015, 21:13
|
Аспирант
|
|
Регистрация: 04.05.2011
Сообщений: 49
|
|
Сообщение от Яростный Меч
|
Обычно логика такая (если по уму делать):
есть массив (очередь), и есть указатель на текущий пункт в нем. Всё что перед указателем - "область повторов", прочее - "область отмен" (обе области могут быть пустые).
Функция undo - если есть команды в "области отмен", отменяем команду, на которой стоит указатель, перемещаем оный на шаг назад.
Функция redo - если есть команды в "области повторов", перемещаем указатель на шаг вперед и выполняем команду под ним.
Функция action (юзер хочет что-то сделать) - удаляем всё из "области повторов", формируем команду, ставим перед указателем, делаем redo. Если в очереди стало больше 10 элементов, удаляем самый старый.
Каждый элемент в очереди - команда, которую можно выполнить или отменить.
|
Что-то я не понял, так что-ли?:
action и redo у меня не зависимы, action происходит в редакторе, а redo конкретно по кнопке исполняется
var history = [];
var ukazatel;
function redo() {
if( ! history[ ukazatel + 1 ] ) {
return false; //Нет в области повторов
}
ukazatel++;
command = history[ ukazatel ];
//Выполняем
}
function undo() {
if( ! history[ ukazatel - 1 ] ) {
return false; //Нет в области отмен
}
command = history[ ukazatel ];
//Отмена
ukazatel--;
}
function action() {
if( ukazatel == undefined )
ukazatel = 1;
else
ukazatel++;
history[ ukazatel-1 ] = COMMAND; // Добавляем команду
if( history.length > 10 ) {
history.pop(); // Удаляем последний элемент
}
}
|
|
07.01.2015, 21:38
|
Профессор
|
|
Регистрация: 12.04.2010
Сообщений: 557
|
|
Вот набросок очереди команд:
function CommandQueue(limit) {
this._limit = limit || 10;
this._arr = [];
this._pointer = -1;
}
CommandQueue.prototype.undoCount = function() {
return this._pointer + 1;
};
CommandQueue.prototype.redoCount = function() {
return this._arr.length - this._pointer - 1;
};
CommandQueue.prototype.undo = function() {
if (!this.undoCount()) {
return false;
}
this._arr[this._pointer].undo();
this._pointer--;
return true;
};
CommandQueue.prototype.redo = function() {
if (!this.redoCount()) {
return false;
}
this._pointer++;
this._arr[this._pointer].redo();
return true;
};
CommandQueue.prototype.action = function(command) {
this._arr.splice(this._pointer + 1, this.redoCount(), command);
this.redo();
if (this._arr.length > this._limit) {
this._arr.shift();
this._pointer--;
}
};
использование:
var q = new CommandQueue(10);
q.action({
undo: function() {...},
redo: function() {...}
});
|
|
07.01.2015, 23:22
|
Аспирант
|
|
Регистрация: 04.05.2011
Сообщений: 49
|
|
Спасибо, вы очень помогли. Разобрался. Вопрос решен
Последний раз редактировалось makar3000, 08.01.2015 в 14:26.
|
|
|
|