У Web-программистов сложилась добрая традиция - в любую даже самую простейшую страницу по дефолту подключать jquery. Я ничего не имею против этой библиотеки. Она шикарна. Она лучшая в своем роде, и продвинула и продвигает современный web далеко вперед. Повсеместный переход сайтов на ajax также связываю с этой библиотекой.
Однако тут есть одно НО. В простейших проектах: небольшая анимация, баннеры, или любую другую логику, где не требуется работа с DOM или ajax, надобность в лишних 90кб скриптов отпадает. Особенно критично это для мобильных устройств. И дело не столько в лишних килобайтах, а в том, что такие скрипты напрасно грузят и без того занятый процессор.
Сперва я хотел написать все на vanila.js, но кросплатфоменность в среде мобильных приложений та еще головная боль, поэтому решено было выбрать легковесный аналог jquery - jQLite.
По объему jQLite всего 14кб, против 90кб сжатой jQuery. Само собой, в ней не все возможности старшей сестры, а лишь необходимый минимум.
Из доступных по умолчанию методов
.each(function...) .addClass(name) .removeClass(name) .toggleClass(name) .css([name/obj[, value])] .show(callbackFunction...) .hide(callbackFunction...) .hasClass(name) .html(htmltext) .parent([selector)] .parents([selector)] .prev([selector)] .next([selector)] .children([selector)] .eq(index) .first() .last() .index([selector)] .append(obj) .remove([filter)] .empty() .val([value)] .attr([name/obj[, value])] .bind(eventName, function...) .trigger(eventName[, array))] .data(key [, value))] .removeData(key) .find(selector) .end()
Нет ни wrap-ов ни fade, ни даже animate. Однако библиотека все еще отлично ищет по дереву DOM, как классы и идентификаторы, так и более сложные селекторы. Тоже с понятными ограничениями.
| Selector Type | Syntax |
| Id | #foo |
| Element | div or span or table |
| Class | .bar or div.baz |
| Multiple class | div.button.jq |
| Descendant | div.jq span.hotlink |
| Multiples | "div.button, div.link" |
| Attribute |
input[type=hidden], input[type!=hidden], input[type*=hidden] |
Поиска в контексте другого элемента, тоже нет. Это нужно запомнить. Метод find не работает, как должен. В документации написано, что он умеет искать по тегам, однако мне это так и не удалось.
Поддерживаются несколько удобных методов
| jQuery.noop() | Пустое действие |
| jQuery.isFunction(obj) :boolean | Определяет, является ли obj функцией |
| jQuery.isArray(obj) :boolean | Определяет, является ли obj массивом |
| jQuery.isPlainObject(obj) :boolean | Определяет, является ли obj обычным объектом с полями |
| jQuery.merge(obj1, obj2) :Object | Соединяет два объекта в один. работает как с массивами, так и с объектами |
| jQuery.param(obj) :String | Конвертирует массив или объект в строку запроса вида &a=1&b=3 |
| jQuery.makeArray(obj[, results]) :Array | Преобразование объекта в массив. Если вы вторым аргументом подать массив, оба будут объеденены в один |
| jQuery.trim(str) :String | Удалить начальные и конечные пробелы из строки |
| jQuery.inArray(value, array) :Number | Возвращает индекс значения в массиве, или -1, если не найден |
| jQuery.data(elem, key[, data]) :Object | Добавление произвольных данных к элементу DOM, или запрос для данных, связанных с ключом, данные сохраняются, как html5 свойства dataset |
| jQuery.removeData(elem, key) | Удаление произвольных данных из элемента DOM |
Есть и убогая работа с ajax. из поддерживаемых методов только GET запрос.
jQuery.ajax.send("http://www.google.com", function(data, status) {
alert(data);
});
либо подобие метода $.post
jQuery.ajax.send("http://www.google.com",{id:111,s:'поиск'}, function(data, status) {
alert(data);
});
Помните, такой запрос тоже отправится, как GET, а поданный массив преобразуется в GET строку. В этот же массив можно подать информацию о асинхронности запроса
jQuery.ajax.send("http://www.google.com", {async:false,id:111},function(data, status) {
alert(data);
});
при таком запросе, скрипт не продолжит работу пока, не завершится запрос.
Обработчики событий, к которым мы привыкли, также ограничены.
.click(function...) .mouseover(function...) .mouseout(function...) .mouseup(function...) .mousedown(function...) .change(function...) .focus(function...) .blur(function...) .submit(function...)
Но метод bind работает с куда большим числом событий
click,dblclick,mouseover,mouseout,mousedown,mouseup,keydown,keypress,keyup,focus,blur,change,select,error,load,unload,scroll,resize,touchstart,touchend,touchmove
Метода unbind нет.
Если изначально писать всю логику на этой библиотеке, то вы скорее всего придете к своей цели. Но, что если подключить ее к готовому проекту, или к стороннему компоненту (календарю, выпадающему меню, и т.д.)
Тут возникнут неизбежные проблемы отсутствия необходимых методов. На выручку придет расширяемость библиотеки по средствам плагинов, такая же, как и у jQuery.
К примеру, некий плагин ругается на то, что у нас нет метода unbind, нет ничего проще. выше пишем
$.fn.unbind = function(){ return this; }
Теперь он есть, хоть и ничего не делает.
А как же анимация? - спросите Вы. К хорошему быстро привыкаешь и анимацию в играх или баннерах, мы не задумываясь делаем методом animate. Великолепный и очень удобный метод. Но его ведь нет, помните?
К слову, анимация в играх - это не что-то эфимерное. Это просто цикл, с некой сменой состояния, каждую итерацию. Берем любую игру с itunes, обычно я покупаю при помощи Игротрек. Любая игра, к примеру гонки - это смена абсолютного состояния объекта (в данном случае автомобиля) по top и left с течением времени.
Все просто, реализуем плагин jQLite.animate.
$.fn.animate = function( options,speed,callback ){
var time_on_tick = 10;
return this.each(function(){
var that = this;
var ticks = {}, starts = {};
for(var key in options){
starts[key] = parseFloat($(that).css(key)); // текущее положение
var arrow = starts[key]<options[key]?1:-1; // направление убывающее или возростающее
ticks[key] = arrow*Math.abs(starts[key]-options[key])/(speed/time_on_tick); // расстояние, которое проейдет анимация за один кадр
};
(function(){
var do_count = 0;
for(var key in options){
// если не достигли точки конца анимации
if( Math.abs(starts[key]-options[key])>5 ){
//то сдвигаем элемент на n пикселов
$(that).css(key,starts[key]+=ticks[key]);
do_count++;
}else delete options[key];
}
// если не все анимации "отстрелялись"
if( do_count )
setTimeout(arguments.callee,time_on_tick);
else callback.apply(this);
})(1);
});
};
$('#execBtn').css('position','absolute').animate({left:100,top:2000},3000,function(){ alert('finish'); });
И пример использования:
Так и строится анимация в играх. Все просто, каждый кадр смещаем положение объекта на n пиксел.
Вот и все, какие-то методы можно просто дописать, чтобы их вызов не вызывал ошибок, какие-то придется функционально повторить. Но оно того стоит. Поверьте!

