7 років тому…
Раптово навігація по DOM стала простий
В ті часи навігація по DOM була дуже складною. Можна було посперечатися - якщо у вас виходило щось зробити в Firefox 1.5, то в IE6 це не працювало.
Простота, з якою можна було вивчити jQuery, стала для мене плюсом. Вся навігація по DOM робилася за допомогою CSS-селекторів (реалізовано це було якийсь божевільної магією з «чорного ящика», яку придумав Джон Резіг) - головне, що це заощаджувало мої обмежені розумові ресурси, і, коли я отримував потрібні мені елементи DOM , я вже міг робити з ними все що завгодно (показувати, приховувати, анімувати і т.п.)
розуміння Ajax
Отже, мені потрібно було працювати з об'єктом XMLHttpRequest. Коли я побачив його вперше, мені коштувало зусиль зрозуміти, як працює подія onreadystatechange і пара this.status і this.readyState. jQuery, як і ряд інших бібліотек, розібралася з тим жахом, який представляли собою XHR-запити в IE через ActiveX ...
jQuery відразу і надовго стала моїм звичайним інструментом. Це був мій «швейцарський ніж», якщо запозичити назву доповіді Адама!
Назад в майбутнє: сьогодні
Давайте промотали стрічку вперед і повернемося в сьогоднішній день. Що сталося за ці роки?
За ці сім років відбулося досить багато. Ймовірно, одним з найважливіших кроків вперед стала поява в браузерах querySelectorAll.
Ендрю Ланні (з PhoneGap і Adobe) написав неймовірно просту функцію:
Це просто і прекрасно.
Я взяв його ідею, трохи розвинув її і використовував в ряді досить специфічних проектів, додавши підтримку для чейнінга, циклів і спростивши синтаксис. У стислому вигляді всі займає менше 200 байт. Сенс цього в тому, що зараз у нас є вбудована в браузери підтримка для ряду функцій, і я намагаюся брати до уваги аудиторію свого проекту, перед тим як за замовчуванням підключати jQuery.
У яких випадках я завжди використовую jQuery
Перш ніж я розповім про те, як я можу обходитися без jQuery, бути «голим» - давайте я розповім про випадки, коли я точно включаю jQuery в проект. Є кілька досить специфічних причин, які змушують мене або починати прямо з jQuery, або перемикатися на неї з якогось спеціально написаного рішення.
Перед цим я повинен зробити застереження щодо випадку, коли я абсолютно точно не використовую jQuery: якщо я намагаюся відтворити баг в браузері, я ніколи не використовую бібліотеку. Якщо ви намагаєтеся знайти баг, щоб можна було повідомити про проблему, необхідно, щоб в прикладі було якомога менше коду (звичайно, крім тих випадків, коли ви відправляєте повідомлення про помилку всередині jQuery!).
1. Коли проект повинен працювати в застарілих браузерах
BBC досить чітко озвучили, що саме вони називають сучасним браузером. і по деякому міркуванні це і є той ознака, по якому я вирішую, включати jQuery за замовчуванням чи ні.
Якщо я знаю, що я повинен працювати з несучасними браузерами, і вони складають частину ядра аудиторії, то я почну з jQuery всередині свого коду.
Що значить «сучасний»? За великим рахунком, відповідь проста: чи підтримує браузер querySelectorAll. BBC застосовує наступний тест на відповідність вимогу сучасності:
Я знаю напам'ять, що IE8 не підтримує addEventListener (хоча і існує Поліфем), так що, якщо підтримка цього браузера важлива для проекту, я розумію, що не хочу починати проект з хаков для IE8.
Не те щоб я хочу сказати, що ті проекти, які я починаю без jQuery, не підтримуватимуть IE8. Швидше - що потрібно починати з малого і робити розробку простий з самого початку. Якщо я почну проект з оберемки хаков - проблем не оберешся.
І ще я вважаю це тим випадком, «коли складність переважує простоту».
2. Коли я роблю щось дешево і сердито
Якщо я створюю якийсь концепт, тестую ідею або просто щось накидаю і відправляю в JS Bin. зазвичай я просто додаю jQuery за замовчуванням. Так мені не доводиться зайвий раз думати.
Без jQuery!
Напевно, ви думаєте: «Так, Ремі використовує jQuery, а якщо немає, то просто переписує всі фічі сам?»
Я абсолютно не хочу винаходити велосипед. Якщо я виявляю, що, розробляючи без jQuery, я в підсумку сам переписую з нуля її функціональність, тоді, ясна річ, я просто витрачаю свій час даремно.
Ні, все не так. Просто є досить багато сценаріїв, в яких я буду писати код свого застосування без бібліотеки, спираючись на вбудовані в браузер технології. Якщо якась частина цих технологій не підтримується в тому чи іншому браузері, я можу вдатися до поліфілії - але тільки після ретельного розгляду і розуміння, що це має сенс.
Отже, як я живу без jQuery, і наскільки повною можна вважати підтримку потрібних технологій в браузерах?
document.ready
Навіть коли я використовую jQuery, якщо у мене (або моєї компанії) є контроль над проектом, я дуже рідко використовую document.ready (або його коротку версію: $ (function)).
.attr ( 'value') і .attr ( 'href')
Мені завжди стає сумно, коли я бачу, як jQuery використовується для того, щоб отримати значення елемента :
Справа тут не в jQuery. Це просто нормальна практика. Потрібно, щоб в коді просто було написано:
Ще люди досить часто використовують jQuery для того, щоб отримати href посилання: $ (this) .attr ( 'href'). але можна цілком легко отримати шлях і з DOM: this.href. Зверніть, правда, увагу, що this.href дещо відрізняється: це абсолютний шлях, оскільки ми тут говоримо про DOM API, а не сам елемент. Якщо ви хочете отримати значення атрибута (як це працює в разі jQuery), ви можете використовувати this.getAttribute ( 'href').
Ще є сценарій, в якому ви встановлюєте клас для елемента, і тут вам теж не потрібна jQuery, якщо ви просто додасте клас. Скільки разів я бачив:
Але навіщо, коли можна так?
Якщо у
вже може бути який-небудь клас, то просто припишіть новий до рядка (jQuery теж потрібно звертатися до властивості className): document.body.className + = 'hasJS'.Тут ми починаємо натикатися на проблеми з іменами класів і відстеженням того, у яких елементів якого класу є, а якого немає. Але в браузерах є і така функціональність.
classList - додаємо, видаляємо, перемикаємо
Властивість classList з специфікації HTML5 підтримується всіма останніми версіями браузерів (крім IE9 - але в цьому випадку я можу використовувати Поліфем).
Красиво, чи не так? А видаляти?
Або можна зробити так:
Але більше вражає вбудована підтримка перемикання класів:
Для додавання декількох класів потрібно додати їх як аргументи через кому:
Є, звичайно, деякі проблеми, на кшталт цієї, з нового рядка:
Жахливо! Але, з іншого боку, я знаю проблемні місця і обходжу їх стороною. В принципі, ми виросли, працюючи з браузерами саме за такими принципами.
Збереження даних
Зберігання довільних даних в елементах з'явилося в jQuery в версії 1.2.3, а зберігання об'єктів - в 1.4, тобто вже досить давно.
У HTML5 є вбудоване зберігання даних усередині елементів, але між jQuery і вбудованою підтримкою є фундаментальна різниця: dataset в HTML5 не підтримує зберігання об'єктів.
Але якщо ви зберігаєте рядки або JSON, тоді вбудована підтримка працює ідеально:
На жаль, вбудованої підтримки немає в IE10 (звичайно, можна додати Поліфему і все прекрасно запрацює - але це потрібно брати до уваги при використанні dataset).
Як я вже говорив, jQuery допомогла мені зрозуміти Ajax в повній мірі. Зараз Ajax - це досить просто. Звичайно, у мене немає жодних додаткових опцій, але, здебільшого я просто виконую XHR GET або POST-запити з JSON.
Коротко і просто. XHR - це зовсім не складно, а зараз є і хороша документація. Розуміння того, як XHR насправді працює і що з його допомогою можна зробити, дає нам більше можливостей.
Як щодо подій прогресу? Подій, прив'язаних до прогресу завантаження? Що щодо відправки ArrayBuffer. А якщо потрібно розбиратися з CORS і заголовком xml-requested-with?
Для цього вам знадобиться прямий доступ до об'єкта XHR (я знаю, що це можна отримати і з jQuery), і вам потрібно знати, як влаштований XHR і що з ним можна робити, тому що такі речі, як, наприклад, завантаження файлів через перетягування зараз шалено просто реалізувати за допомогою вбудованої функціональності.
Нарешті форми!
jQuery-плагін для валідації форм був стабільним плагіном з перших днів jQuery, і чесно зробив роботу з формами набагато простіше.
Але незалежно від валідації на стороні клієнта все одно потрібно проводити валідацію на стороні сервера - це необхідно в будь-якому випадку, яку б валідацію ви не робили.
Хочете зробити його обов'язковим полем?
Хочете вирішувати користувачу вводити тільки певні символи?
Навіть в тому випадку, коли я пишу код сам, я виберу requestAnimationFrame замість використання анімацій, заснованих на setInterval.
Джейк Арчибальд підготував відмінні слайди, які показують проблему - setInterval зробить анімацію плавної, і досить скоро почне пропускати кадри:
Крім того, CSS-анімації проходять через той же таймер, що і requestAnimationFrame - його ми і хочемо використовувати.
Так що, якщо ваш браузер це дозволяє, використовуйте CSS-анімації. Звичайно, це складніше, ніж $ foo.animate ( 'slow',
А ось якщо ви просто зробите foo.classList.add ( 'animate'). анімація CSS-класу виконає плавний перехід положення лівої точки елемента. І якщо ви точно знаєте, що це тільки значення зліва, можна використовувати апаратне прискорення, виконавши translateX з translateZ (0).
Ну а як же, чую я ваш крик, як же виклик функції після закінчення анімації? Це теж можна. Хоча синтаксис трошки неприємний:
Зверніть увагу, що e в end рядкова ...
Пара милих людей в Твіттері показали мені свого роду Поліфем для jQuery. який доповнює функцію .animate в тому випадку, якщо в браузері доступні CSS-анімації.
Звідси у мене виникає питання: чому цей плагін в обов'язковому порядку вимагає jQuery?
В сторону: jQuery-плагіни - просто так
Не знаю чому, але мені дуже хочеться боляче вдарити людей, які пишуть такі jQuery-плагіни, для яких насправді jQuery абсолютно не потрібна. / Требуется-контроль-емоцій
@rem У мене те ж саме. Я думаю, десь є група, в якій з цим допомагають, - і, гадаю, досить велика.
Я недавно працював над проектом і дізнався про fitText.js. Я вирішив включити його в свій код, але потім помітив, що для нього потрібно jQuery.
Цей проект використовує такі методи jQuery:
- .extend
- .each
- .width
- .css
- .on (над продуктивністю ніхто особливо не замислювався)
Власне, ось код проекту:
extend використовується на об'єкті, в якому всього дві опції, так що я б переписав його так:
return this.each використовується для того, щоб ітерованих за елементами. Припустимо, що ми хочемо, щоб цей код працював без jQuery: тоді наша функція fitText отримає список елементів (так як чейнінга ми робити не будемо):
$ This.width () отримує ширину контейнера, щоб змінювати розмір тексту. Для цього нам потрібно отримати розраховані стилі і взяти з них значення ширини:
$ This.css використовується для установки значень, так що тут всього лише потрібно задати стилі:
$ (Window) .on ( 'resize', resizer) прикріплює обробник події (якщо ви хочете підтримку в IE8, то потрібно ще включити addEvent):
Насправді, я б пішов ще далі і зберігав би функції ресайз в масиві, і під час операції зміни розміру проходив би по масиву, виконуючи всі ці функції.
Звичайно, тут потрібно трошки більше роботи, але при цьому такі зміни досить легко провести так, щоб робота в якості jQuery-плагіна була б для цього проекту додатковою функціональністю, а не вимогою.
Моя тирада скоро закінчиться: ще мене вбиває, коли я бачу Поліфему якому потрібно jQuery - але я визнаю і контраргумент: надзвичайна поширеність jQuery, напевно, може виправдати те, що стільки проектів пишеться з залежністю від неї.
висновок
Перестаньте думати в парадигмі «функція X не працює в браузері Y». Підходьте під іншим кутом зору. Яке завдання я вирішую? Який інструмент найкраще підійде? Для кого це робиться? Я як і раніше вірю в методологію прогресивного поліпшення, але я не розумію задоволення лізти зі шкіри геть заради того, щоб підтримувати уявну аудиторію користувачів (з тієї причини, що у нас немає даних, які браузери у наших користувачів).
Google (за моїми останніми даними) підтримує останні і передостанні версії браузерів. Я теж намагаюся починати з підтримки цих версій.
Я буду продовжувати використовувати jQuery так, як мені зручно, і я продовжу переконувати своїх читачів і слухачів, що фронтенд-розробники повинні знати, що можуть браузери, з якими вони працюють.
Отже, на цьому я закінчую і сподіваюся, що цей текст був вам корисний.
Можливо, деякі з вас вже знали все це (правда, в такому випадку у мене виникає питання, навіщо ви це читаєте), однак я сподіваюся, що хоч комусь я показав, що за межами jQuery є ще цілий світ, і ви можете почати освоювати його прямо зараз в одному зі своїх проектів.
Однак більшості з вас я приніс сніг взимку. Ви вже згодні зі мною. Ви вже вірите в стандарти, робите все правильно, вчіться і утворювати. Але ви повинні допомогти людям, які не отримують цієї інформації.
Вам потрібно ділитися своїми відчуттями з іншими людьми. Тепер ви - експерти, і ви повинні допомогти оточуючим досягти вашого рівня і перевершити його.
На конференціях будуть потрібні нові доповідачі і нові експерти: це ви.
Матеріали до статті
Zepto.js як альтернатива.
Насправді, є і ще одна важлива деталь щодо jquery - він в 99% випадків вже закешируваний в браузері.
Взагалі, одна справа - писати простий функціонал, а інше - не дуже простий. Саме тут фреймворк і врятує, економлячи час, зменшуючи обсяг коду і збільшуючи простоту розуміння цього коду кимось ще. Коли ж код дуже складний, в проект нерідко тягнуть таких монстрів, що потім виходить не проект, а лагалово навіть на негайних машинах. Особливо цим страждає extjs та інше подібне. Чим вище рівень фреймворка, тим більше геніальним повинен бути розробник, адже йому доведеться не тільки писати алгоритми, а ще й вміти перемагати внутрішні недоліки використовуваного інструменту. jquery в цьому сенсі - цілком низькорівневий і в цілому негайний.
Згоден з Васею. Правда, як можна ігнорувати jQuery, коли його використовують практично всі.
З іншого боку я поки вчуся і не розумію чому не можна замінити використовувати поліфілії в IE, а для нових браузерів писати програми на вбудованому API.
А який сенс в jquery 2 це ще складніше зрозуміти, т.к він старі ие не підтримує.
Як співається в пісеньці: "Jquery is something you can not ignore. Write less, do more :)".