Javascript onbeforeunload — як попереджати юзера про незбережені дані у формі



Напевно кожному знайома ситуація: пишеш ти комусь довжелезне повідомлення, допис на форумі, або просто заповнюєш велику форму реєстрації, і тут РАПТОВО випадково клацаєш на якесь посилання чи закриваєш вкладку… і все те, що ти натхненно писав протягом останніх n хвилин, зникає. Кілька секунд йде на усвідомлення того, що сталось, і прийняття факту, що вже нічого не повернути. Після цього ти проклинаєш розробників сайту, рвеш на собі волосся, розбиваєш монітор, хапаєшся за сокиру і йдеш вбивати.

Тому хороший сайт повинен попереджати юзера про те, що у формі залишились незбережені дані, коли той пробує покинути сторінку. Звісно, таке не варто робити для всіх форм підряд. Наприклад, для форми логіну, де користувач вводить лише юзернейм і пароль, це зайве. Але для форм, де передбачається введення великої кількості даних, видавати таке попередження є правилом хорошого тону.

Робиться таке дуже просто через івент onbeforeunload у Javascript.

onbeforeunload спрацьовує тоді, коли користувач пробує покинути сторінку (будь-яким чином — закрити вікно/вкладку, оновити сторінку, перейти за якимось посиланням і тд.) Щоб при закритті сторінки відкрилось попередження, треба просто обробити цей івент. А саме, коли він спрацьовує, треба викликати якусь функцію, яка має всього-на-всього повернути певний текст. Браузер використає цей текст в якості повідомлення, яке буде показано користувачу. Щоправда, Firefox ігнорує текст, наданий сайтом, і завжди показує своє стандартне повідомлення. Але це ще нічого, наприклад, Opera взагалі не вміє працювати з onbeforeunload, там сторінка просто закриється, і все. В Chrome, IE, Safari все добре :)

Найпростіший приклад обробки івенту onbeforeunload:



Якщо додати до сторінки такий скрипт, то при спробі покинути її, у Chrome ми побачимо таке повідомлення:



А у Firefox — таке:



Тепер нам потрібно зробити так, щоб це повідомлення відображалось не завжди, а лише тоді, коли користувач вніс якісь зміни у форму на сторінці. Як визначити, чи користувач вніс зміни у форму? Просто порівняти ті дані, які були у формі при завантаженні сторінки, і ті, які є у формі при спрацюванні onbeforeunload.

Для початку створимо сторінку з простою формою, яка складається лише з одного поля для тексту і однієї кнопки. HTML код:


А тепер напишемо скрипт, який перетворить цю туфтову і примітивну форму в круту та інтерактивну:


Скрипт зовсім елементарний. При відкритті сторінки спрацьовує івент onload і викликається функція saveOldData(). Вона витягує вміст з форми someForm і записує його у змінну oldData. Далі на сторінці щось відбувається, юзер щось робить, можливо, міняє вміст форми, а може й ні. При закритті сторінки спрацьовує onbeforeunload, викликається функція toCloseOrNotToClose(). Спершу вона зберігає поточний вміст форми у змінну newData, а потім перевіряє, чи oldData і newData однакові. Якщо ні, значить користувач вніс зміни у форму, і тоді відображається попередження.

Все круто, але є одне але :). Якщо для надсилання даних із форми використовується метод POST, то коли юзер натисне кнопку «Надіслати», форма спробує перенаправити його на іншу сторінку, і йому, знову ж таки, буде відображено повідомлення про те, що у формі є незбережені зміни. У цьому випадку показувати таке повідомлення тупо, бо ж юзер якраз і хоче зберегти ці зміни, натискаючи кнопку. Тому треба трошки підправити наш код.

Додамо змінну isDataSubmitted, яка буде відповідати за те, чи були дані з форми збережені. За замовчуванням вона буде дорівнювати false. Тепер додамо функцію submitData(), яка буде міняти значення isDataSubmitted на true. В функцію toCloseOrNotToClose() крім перевірки на те, чи нові дані з форми відрізняються від старих, додамо перевірку на те, чи isDataSubmitted дорівнює true.


І зробимо так, щоб при кліку на нашу кнопку викликалась функція submitData().


Ось і все. Тепер попередження буде відображатись тоді, коли юзер вніс зміни у форму і покидає сторінку таким чином, що ці зміни можуть втратитись.

Архів з цим прикладом тут.

На додаток, стаття від Студії Лебедєва про те, як робити хороші з точки зору юзабіліті форми http://www.artlebedev.ru/tools/technogrette/etc/forms/
19 жовтня 2013 о 17:39