Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development

Створення системи редагування для використання на місці

by
Difficulty:IntermediateLength:LongLanguages:

Ukrainian (українська мова) translation by AlexBioJS (you can also view the original English article)

(* системи редагування, яку можна використовувати на тій самій сторінці, де розташовується оригінальний текст. Тут і надалі примітка перекладача). Примушувати користувачів переходити між декількома сторінками лише для того, щоб відредагувати текст, – це минулий вік. У цьому посібнику ви дізнаєтеся, як створити систему редагування для використання на місці, подібну до тої, що використовується на популярних сайтах на зразок Flickr.


Від автора

Враховуючи весь цей галас довкола Web 2.0 (* термін відноситься до сайтів, де особливе значення відводиться контенту, створюваному користувачами, зручності використання, культурі сумісного створення контенту та функціональній сумісності з іншими системами, пристроями...) зручність використання тепер важлива, як ніколи раніше. Наявність можливості відредагувати якийсь контент без потреби переходу на іншу сторінку, – те, що багатьом користувачам дуже потрібно. На багатьох відомих веб-сайтах цю можливість вже реалізовано вельми ефективно. Якщо використовували Flickr, то, напевно, вже бачили, як це виглядає в дії.

Думаю, що краще один раз побачити, ніж сто раз почути. Ознайомтеся з демоверсією та пограйтеся з нею самі.

Сьогодні ми розглянемо, як реалізувати цю можливість за допомогою, ви вгадали, нашої улюбленої бібліотеки JavaScript, jQuery. Зацікавило? Давайте одразу перейдемо до справи!

Вимоги до системи

Перед тим як ми перейдемо до розгляду того, як реалізувати потрібні нам функціональні можливості, ознайомтеся з деякими міркуваннями з приводу вимог до системи та остаточних рішень.

  • Нам потрібно надати користувачу можливість редагувати контент, залишаючись на тій самій сторінці. Це вихідна вимога.
  • Система повинна або працювати загалом, або не працювати зовсім (* за принципом «все або нічого»). Якщо у користувача відключено JS, то ми не хочемо вдаватися до чудних хитрощів.
  • Користувач повинен бути в курсі, що контент можна редагувати. Він повинен це зрозуміти через незначну зміну кольору фону на світло-голубий.
  • При виборі способу активації можливості редагування ми маємо пару варіантів. Ми можемо надати користувачам цю можливість або коли вони один раз натискають кнопку миші, або коли двічі. Я зупинив свій вибір на останньому варіанті, оскільки випадкові подвійні натискання кнопки миші відбуваються рідше, ніж випадкові одиночні. Для того щоб його змінити, потрібно всього-на-всього змінити аргумент методу bind.
  • Користувач повинен мати можливість зберегти внесені зміни або відказатися від них.
  • Обробники для зберігання або редагування можуть бути запущені двома способами. Завдяки подіям, що виникають при роботі з клавіатурою, або подіям, виникаючим при роботі з мишкою. Я зупинив свій вибір на останньому варіанті, оскільки подіям, що виникають при роботі з клавіатурою, не вистачає визначеності (* вони можуть виникнути і при виконанні нами дій, не пов'язаних конкретно з нашою системою редагування).
  • Щодо подій, виникаючих при роботі з мишкою, то ви могли би використовувати або традиційні кнопки, або звичайні посилання. Я вибрав посилання без особливої на те причини.
  • Користувач повинен мати можливість поновити редагування, навіть якщо він натискає за межами поля вводу або залишає сторінку та повертається знову.
  • Також у користувача повинна бути можливість редагувати як можна більше полів одночасно.

Тепер, коли ми склали список потрібних нам можливостей, то можемо перейти до того, як ми їх будемо реалізовувати.

План дій

Тепер нам потрібно буде скласти послідовний план того, що потрібно виконати.

Крок 1: Нам потрібно буде додати клас editable до кожного елемента, для якого потрібно реалізувати можливість редагування тексту на місці.

Крок 2: Далі нам буде потрібно додати класи для зміни стильового оформлення елемента у випадках, коли поверх нього переміщається курсор, для кожного редагованого елемента, щоб звернути увагу користувача до того, що контент того елемента можна редагувати. Ми додамо та видалимо ці класи за допомогою JavaScript, а не CSS. Це робиться, головним чином, для пристроїв або браузерів з відключеним JavaScript. Ми не хочемо відправляти їм хибні візуальні підказки.

Крок 3: При подвійному натисканні на редагованому елементі нам потрібно замінити його текстовим полем зі старим текстом.

Крок 4а: Коли користувач хоче зберегти внесені зміни, нам потрібно скопіювати значення поля до батьківського елемента та видалити поле для вводу даних.

Коли 4b: Або коли користувач хоче відмовитися від внесених змін, то нам потрібно повернути старий контент та видалити поле вводу.

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

Головний HTML-код

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

Як ви бачите, не враховуючи стандартний код, ми маємо два невпорядковані списки. Кожний елемент li має клас editable, що вказує на те, що його контент можна редагувати.

Також ми підключили бібліотеку jQuery та наш власний файл з кодом скрипта.

CSS-код

Тут нема нічого особливого. Просто кучка коду для позиціонування елементів та додання стильового оформлення.

Зверніть особливу увагу на класи editHover та noPad. Ми ними скористаємося зовсім скоро.

Код JavaScript

Тепер, коли ми маємо базовий код розмітки та деяке базове стильове оформлення, ми можемо взятися за написання коду для реалізації потрібних функціональних можливостей. Обов'язково зверніть увагу на те, що ми будемо дуже широко використовувати jQuery. Точніше, нам буде потрібна щонайменше версія 1.3 або пізніша. Якщо ви будете використовувати будь-яку більш ранню версію, то демоверсія працювати не буде.

Додавання класів для зміни стильового оформлення елемента у випадках, коли поверх нього переміщається курсор.

Hovers

Як було згадано раніше, нам потрібно буде додати світло-голубий фон до редагованих елементів, щоб вказати, що їх можна редагувати. Ми вже створили клас editHover для цього.

За допомогою цього невеликого фрагменту коду реалізується ця можливість. Ми використовуємо метод jQuery hover для додання класу editHover, коли поверх елемента переміщено курсор, та його видалення, коли ні. Ми використовуємо this, щоб послатися на конкретний елемент, поверх якого переміщено курсор. Якщо би ми скористалися замість цього в якості селектора .editable, то до всіх елементів без виключення було би додано вищезазначений клас. Так що ми використовуємо this, щоб отримати тільки той елемент, який нам потрібен.

Заміна елементів

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

Ми прив'язуємо функцію replaceHTML до події dblclick для редагованого елемента за допомогою тієї однорядкової програми (* програма, ефект якої значно більший, ніж можна було би чекати, виходячи з її розміру). Тепер ми можемо перейти до заміни елементів.

Давайте пройдемося по нашому коду рядок за рядком.

Я реалізую функціональні можливості в окремій іменованій функції, а не анонімній, через конкретну причину: я буду використовувати цю функцію декілька разів. Далі ми зберігаємо контент елемента для використання в майбутньому за допомогою методу html jQuery та видаляємо всі лапки, оскільки через це врешті-решт псується остаточний результат.

Тепер, коли наш контент надійно збережено для подальшого використання, ми можемо замінити наші елементи. Для початку ми звільняємо елемент li, передаючи методу html в якості аргументу пустий рядок. Далі йде деякий стандартний HTML-код для додання поля вводу. Ми додаємо йому деякі класи для задання його стильового оформлення. Важливіше те, що ми встановлюємо в якості значення його властивості value оригінальний текст, що міститься в елементі, який зберігається в oldText. Також ми додаємо декілька посилань для реалізації можливості зберігання та відказу від внесених змін. Також ми додали їм класи, щоб їх можна було легко отримати та додати для них стильове оформлення.

Як завжди, ми використовуємо this для отримання елемента, на якому було згенеровано подію.

Зберігання внесених змін

Edited Text

Для початку дозвольте мені вам представити метод live jQuery. Ви, напевно, на часто зустрічалися з ним до цього, так що я коротенько обмалюю вам його:

Ви не можете підв'язати обробники до подій, генерованих елементами, яких навіть не було в DOM, коли сторінка та JavaScript-код було завантажено. Якщо ви використовуєте звичайні функції для прив'язування обробників, то їх код не спрацює через вищезазначену причину. Ця проблема вирішується за допомогою методу live.

За допомогою нього обробники прив'язуються до подій незалежно від того, коли було створено елемент. За подробицями про цей метод звертайтеся до офіційної документації.

Давайте тепер поглянемо на код. Спочатку ми підв'язуємо код, що міститься в анонімній функції, до події click. У цій функції ми спершу зберігаємо текст, що міститься в полі для вводу. Це не так-то легко зробити, оскільки в поля для вводу нема ID. Так що ми для початку отримуємо елемент для додання форми, що є сиблінгом (* потомство одних батьків) елемента посилання для зберігання змін, і потім проходимо по дереву, щоб знайти елемент input. Потім ми копіюємо його значення після того, як видалили всі лапки, які можуть в ньому бути.

Потім ми отримуємо батьківський елемент посилання, елемент li, і замінюємо його HTML-контент на текст, скопійований нами в попередньому кроці.

Цей блок коду можна було би запросто записати в один рядок, проте я розбив його на два рядки для покращення читабельності коду.

Відмова від внесених змін

Тут все так просто, як виглядає. Оскільки користувач не хоче зберігати зміни, то ми просто замінюємо HTML-контент батьківського елемента на оригінальний текст, який скопіювали раніше до змінної oldText.

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

Прив'язування та відв'язування обробників

Якщо ви протестували наш код на цьому етапі, то, напевно, зіткнулися з наступним багом, що порушує роботу системи: коли користувач двічі натискає кнопку миші у з'явившемуся полі для вводу даних, то воно наповнюється HTML-контентом системи редагування. Спробуйте самі. При кожному наступному подвійному натисненням у полі для вводу даних додається додатковий фрагмент тексту. Ця проблема була би, напевно, набагато серйозніше, якщо би ви вибрали click в якості події, при виникненні якої запускаються обробники.

Щоб це виправити, нам потрібно відв'язати обробник подій лише для того елемента, на якому виникає подія, та прив'язати його доразу після того, як користувач переходить або за посиланням для зберігання внесених змін, або за посиланням для відказу від них. Давайте тепер це реалізуємо.

Наші попередні блоки коду тепер повинні бути відредаговані наступним чином:

Ми відв'язуємо обробник для елемента, на якому було згенеровано подію. У решти елементів з класом editable як і раніше є їх обробники, і вони відреагують на події.

Далі ми прив'язуємо цей обробник назад незалежно від того, чи вирішує користувач їх редагувати або ні. Якщо ми не підв'яжемо його заново, то поле можна буде редагувати тільки один раз. При повторному подвійному натисненні на них, обробники більше не прив'язані до подій. Ми виправляємо це завдяки прив'язуванню обробників назад до подій.

Декілька невеликих поправок

Останній фрагмент коду призначений виключно для того, щоб покращити зовнішній вигляд нашого ефекту. Якщо ви помітили, в елементів li задано невеликі поля, щоб покращити зовнішній вигляд тексту в них. Проте коли текст видаляється та змінюється на текстове поле, то результат виглядає жахливо та псує наш ефект. Нам потрібно, щоб текстове поле займало такий самий простір, як і оригінальний текст. Нам потрібно, щоб текстове поле займало такий самий простір, як і оригінальний текст. Враховуючи це, ми додаємо клас noPad для елемента, коли на ньому двічі натиснули кнопкою мишки, та видаляємо знову, коли користувач зберігає або відказується від внесених змін.

Ми відв'язуємо обробник для елемента, на якому було згенеровано подію. У решти елементів з класом editable як і раніше є їх обробники, і вони відреагують на події.

Весь код

Нижче показано, як виглядає весь код:

Непогано. П'ятдесят незвичайних рядків для додавання деяких просунутих можливостей.

Вдосконалення демоверсії: серверна частина

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

Додання цієї можливості не повинно викликати труднощів, проте зверніть на це увагу. Код вище було написано всього-на-всього для того, щоб проілюструвати зразок розглядуваної тут системи, а не для того, щоб використовувати його в якості фінальної версії системи. Тому я не став додавати додаткові атрибути ID для елементів та атрибути name для текстових полів. У коді вашої фінальної версії системи обов'язково додайте їх всі, так щоб для атрибута name текстового поля можна було задати осмислене значення, завдяки чому в серверної частини була би можливість зрозуміти, який фрагмент даних потрібно оновити.

Для додання AJAX-запиту наш обробник для зберігання внесених змін повинен був би бути оновлений наступним чином:

Пам'ятайте, що для того щоб серверна частина якось розуміла те, що ви відправляєте, вам потрібні деякі додаткові дані окрім оновленого тексту, завдяки чому додаток розуміє, які дані потрібно редагувати. Ви могли би запросто відправити більше одного фрагменту даних скрипту за потреби.

Завершення

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

Є питання? Хочете побажати щось приємне? Маєте якісь критичні зауваження? Перейдіть до розділу з коментарями та залиште мені коментар. Вдалого вам програмування!

  • Підпишіться на нас на Twitter або на Nettuts+ RSS Feed, щоб бути в курсі про нові посібники та статті з веб-розробки.


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.