Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.01.2015, 01:30
Аспирант
Отправить личное сообщение для makar3000 Посмотреть профиль Найти все сообщения от makar3000
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 07.01.2015, 11:28
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 22.03.2012
Сообщений: 3,744

Сообщение от makar3000
 if( history.length > 11 ) { // на 10 раз
     h_i = 1;
     history = [];
   }
то есть ты каждый раз обнуляешь после 11 сохранений
копируй или смещай элементы массива вперед, в конец добавляй последний результат сохранения
Ответить с цитированием
  #3 (permalink)  
Старый 07.01.2015, 14:37
Аспирант
Отправить личное сообщение для makar3000 Посмотреть профиль Найти все сообщения от makar3000
 
Регистрация: 04.05.2011
Сообщений: 49

Делал вместо очистки .pop() все работало! Но если по второму кругу нажимать back() то в массиве были данные из первого круга и возвращалось то что было в первом круге а не во втором
Ответить с цитированием
  #4 (permalink)  
Старый 07.01.2015, 15:22
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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>
Ответить с цитированием
  #5 (permalink)  
Старый 07.01.2015, 17:15
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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>
Ответить с цитированием
  #6 (permalink)  
Старый 07.01.2015, 17:51
Профессор
Отправить личное сообщение для Яростный Меч Посмотреть профиль Найти все сообщения от Яростный Меч
 
Регистрация: 12.04.2010
Сообщений: 557

Сообщение от bes
опиши логику переходов по истории
Обычно логика такая (если по уму делать):

есть массив (очередь), и есть указатель на текущий пункт в нем. Всё что перед указателем - "область повторов", прочее - "область отмен" (обе области могут быть пустые).

Функция undo - если есть команды в "области отмен", отменяем команду, на которой стоит указатель, перемещаем оный на шаг назад.

Функция redo - если есть команды в "области повторов", перемещаем указатель на шаг вперед и выполняем команду под ним.

Функция action (юзер хочет что-то сделать) - удаляем всё из "области повторов", формируем команду, ставим перед указателем, делаем redo. Если в очереди стало больше 10 элементов, удаляем самый старый.


Каждый элемент в очереди - команда, которую можно выполнить или отменить.

Последний раз редактировалось Яростный Меч, 07.01.2015 в 18:00.
Ответить с цитированием
  #7 (permalink)  
Старый 07.01.2015, 18:46
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 22.03.2012
Сообщений: 3,744

Сообщение от Яростный Меч
Обычно логика такая (если по уму делать):

есть массив (очередь), и есть указатель на текущий пункт в нем. Всё что перед указателем - "область повторов", прочее - "область отмен" (обе области могут быть пустые).

Функция undo - если есть команды в "области отмен", отменяем команду, на которой стоит указатель, перемещаем оный на шаг назад.

Функция redo - если есть команды в "области повторов", перемещаем указатель на шаг вперед и выполняем команду под ним.

Функция action (юзер хочет что-то сделать) - удаляем всё из "области повторов", формируем команду, ставим перед указателем, делаем redo. Если в очереди стало больше 10 элементов, удаляем самый старый.


Каждый элемент в очереди - команда, которую можно выполнить или отменить.
отобрази на мой пример с тремя кнопками
save - action - удаляем все предыдущие элементы массива перед текущим, добавляем элемент в конец массива
back - undo - переходим на предыдущий элемент массива, если он есть
forward - redo - переходим на последующий элемент массива, если он есть
так?
Ответить с цитированием
  #8 (permalink)  
Старый 07.01.2015, 21:13
Аспирант
Отправить личное сообщение для makar3000 Посмотреть профиль Найти все сообщения от makar3000
 
Регистрация: 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(); // Удаляем последний элемент
  }
}
Ответить с цитированием
  #9 (permalink)  
Старый 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() {...}
});
Ответить с цитированием
  #10 (permalink)  
Старый 07.01.2015, 23:22
Аспирант
Отправить личное сообщение для makar3000 Посмотреть профиль Найти все сообщения от makar3000
 
Регистрация: 04.05.2011
Сообщений: 49

Спасибо, вы очень помогли. Разобрался. Вопрос решен

Последний раз редактировалось makar3000, 08.01.2015 в 14:26.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
filter(this,this) как правильно сделать? Smip jQuery 5 23.02.2013 03:07
Как сделать что бы при регистрации человека на моем сайте у него не появлялось... drunkwolfs Общие вопросы Javascript 2 07.08.2012 10:58
Как сделать как в JQ? faforty Общие вопросы Javascript 8 14.11.2011 01:35
Нужно сделать плавное появление текстового поля как на сайте vkontakte.ru paratrooper1981 Элементы интерфейса 1 23.11.2009 18:24
Помогите сделать такое меню(( Lilith Я не знаю javascript 2 02.06.2009 02:31