Функция назад или Ctrl+Z

Представим, что есть страничка, которая редактируется online, с помощью js скриптов. Например вставляю блок на страницу, перемещаю его, добавляю в него текст, одним словом что-то напоминает действия в визуальном редакторе.
Вопрос: Как можно на страничке реализовать кнопки назад и вперёд, как в любой программе, при нажатии на которые происходит откат?
Даже понятия не имею, каким способ и как вообще это реализовать, как запоминать действия. В интернете нет таких решений. Даже не знаю чем это сделать, с помощью php или jquery.
p/s:"Javascript не очень."

8 комментариев

Kylaksizov 09.09.2014 23:56
Немножко дополню.
Пользуюсь библиотекой livequery для работы с динамическим добавлением объектов.
Т.е. что бы работать с добавленным элементом на странице и получать все его свойства например
<div id="test"><div>
- получить css, мне нужно написать так:
$('#test').livequery("click", function(){
   $(this).css();
})

И мне теперь каждое его перетаскивание или изменение нужно как-то запомнить, что бы потом вернуть можно было по шагам. Таких элементов может быть сколько угодно.
Если можно, то детальнее показать решение с комментариями. Заранее благодарен.
Incode 10.09.2014 12:57
@Kylaksizov, для начала, я не понимаю зачем использовать какую-то библиотеку "livequery", если jQuery отлично справляется с динамически добавленными элементами. Для этого используют метод .on() и делегированную обработку событий. Но это отдельный разговор.
Теперь к основному вопросу... Сделал вам пример для одного элемента. Писал на скорую руку, поэтому не нужно его воспринимать, как готовое решение. Я просто попробовал показать сам принцип работы. После каждого изменения положения элемента (в примере это перетаскивание), мы записываем полностью все css-свойства элемента в LocalStorage. С каждым шагом в массив добавляется очередной набор свойств. Когда мы используем rollback (шаг назад или вперед по истории), мы просто берем из массива свойств очередной элемент и подставляем его методом .css() нашему перетаскиваемому блоку.
Понятное дело, что для "перетаскивания", нам бы просто хватило запомнить его позицию сверху и слева, но так как у вас возможно будут разные деформации, то сделал "всё в куче". И конечно же в реальном проекте, нужно следить за переполнение LocalStorage, удалять первый элемент "истории", если хранилище забито полностью. К тому же, если элементом страницы у вас будет очень много, то локальное хранилище может быть и не вариантом (не резиновое оно;) ). Тогда нужно будет Ajax-ом отправлять данные на сервер и хранить их или же в файле json-строкой или же сохранять в БД.
В общем, задача сама по себе не очень сложная, однако, решение её зависит от очень многих "но".
Incode 10.09.2014 13:08
P.S. Если учитывать, что объем LocalStorage около 5Мб, а один "шаг истории" весит около 8кб, то получается, что мы можем сохранить для одного элемента примерно 625 шагов его состояний. Это не мало для одного элемента, но сами понимаете, что если у вас их будут десятки, то цифра будет значительно меньше.
Kylaksizov 10.09.2014 14:55
Функция .on не работает с динамическими добавлениями, могу продемонстрировать, если нужно.
За пример спасибо, только почему он запоминает всего один шаг? Т.е. если я два - три раза перетащу, то он просто возвращается в положение 0 0.
Incode 10.09.2014 16:01
Функция on(), превосходно работает с динамическими добавлениями. И тут бы я мог поставить на кон всю свою репутацию вместе с имуществом ;) Но вы пропустили ключевую фразу "делегированная обработка событий".
По поводу примера - не совсем понял. Протестировал в FF, Chrome, Opera, IE, Safari, делал по двадцать изменений, после перезагрузки еще плюс двадцать и все (40 в сумме) шаги отработали нормально.
Kylaksizov 11.09.2014 10:49
Теперь работает, странно) Но всё же на счёт .on() - как я не пытался не работает она у меня. Если я работаю с уже существующим элементом то да. А если добавляю новый элемент то не работает.
Incode 11.09.2014 14:42
По поводу метода .on() - посмотрите примерчик. Делегированная обработка событий, строится по такой схеме:
$('static_parent').on('event', 'dynamic_child', function(){
   // do something
});
В качестве основного селектора, мы указываем не элемент, который добавляется динамически (dynamic_child), а его родительский элемент (static_parent), который изначально присутствует на странице при её загрузке. Таким родительским элементом, может быть даже <body>, если уж другого, более близкого "родственника" не нашлось ;)
Kylaksizov 11.09.2014 15:21
Видимо я не так делал, спасибо)
Ваш комментарий:
X