Category Archives: javascript
Самый хороший способ подгрузки яваскриптов – тегом script
Использовали мы на проекте одну лебедевскую библиотеку — include.js. Умеет она интересные вещи, вроде последовательной загрузки зависимых библиотек в нужном порядке. Нужно в яваскрипте написать js.include( ‘my/coolwiidget’ );. Работает она, если на пальцах, следующим образом: делается ajax-запрос, которым грузится текст нужного скрипта, потом ищутся в тексте все js.include, делается их подгрузка, после чего делается eval …
Фреймворки для создания MVC-подобной архитектуры на javascript
Выбирал между backbone (habrahabr.ru/blogs/javascript/118782/) и knockout (http://habrahabr.ru/blogs/javascript/121926/). Для выбора полезно почитать stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs. В итоге выбрал knockout — менее монструозный и лично мне показался понятнее, к тому же не навязывает REST и не требует дополнительных библиотек. Он реализует паттерн MVVM, который, думаю, больше подходит для клиентской части web-приложения, чем MVC. На сайте есть подробные доки и …
Lazy load баннеров
Сегодня из-за очередных проблем с sol.adbureau.net было решено реализовать ленивую загрузку баннеров. Начальное решение было использовать iframe, но идея была не очень удачной, т. к. могут быть проблемы с подсчётом кликов, да и модные картинки, увеличивающиеся при наведении, будут вести себя странно. А как этот iframe смотрится в разных браузерах — это вообще сказка) В …
Проблемы рендеринга страниц в Firefox
Имеем флеш-плеер. На некоторых страницах при нажатии на кнопку «плэй» в плеере происходит перезагрузка flash-плеера. После долгих и мучительных разбирательств выяснилось следующее: Flash-player при смене статуса (play/pause) меняет фавикон на сайте следующим кодом:
1 2 |
$("link[rel='shortcut icon']").remove(); $("head").append("<link rel='shortcut icon' href='" + link + "' />"); |
Меняет на всех страницах, а перезагрузка плеера происходит только на некоторых, и только в фф. На этих страницах перед плеером стоял …
Как бороться с повторным добавлением обработчика события в jQuery
Нужно было навешивать и снимать обработчик клика динамически, при этом не затронув чужие обработчики, а их на элементе несколько, каждый ставится своим виджетом. Мой jQuery-ui-виджет навешивает клик только если его ещё нет. Для этого сделан отдельный метод:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
_bindClick: function() { var me = this; var $me = $( me.element ); // боремся с повторным навешиванием обработчика var events = $.data( $me.get(0), 'events' ); var filteredEvents = []; if ( 'click' in events ) { filteredEvents = $.grep( events.click, function( Event ) { return Event.type == 'click' && Event.namespace == me.widgetName; } ); } if ( filteredEvents.length ) { return; } $me.bind( 'click.' + me.widgetName, function( Event ) { // логика клика, к примеру: if ( ! me.options.allowDoubleClick ) { $me.unbind( 'click.' + me.widgetName ); } } ); }, //===========================================================================}}} |
Работа с событиями в jQuery 1.7
В jQuery 1.7 добавили .on() и .off() для единообразия работы с событиями. bind, live и delegate могли вести себя непредсказуемо при использовании вместе. Например, $(document).unbind(‘click’) убирал все live(‘click’)-события со всего документа. Новое API событий .on() and .off() призвано как-то унифицировать систему создания обработчиков событий: Старое API Новое API $(elems).bind(events, fn) $(elems).on(events, fn) $(elems).bind(events, { mydata: 42 }, …
Что такое IIFE
IIFE (Immediately-Invoked Function Expression, «iffy») — немедленно выполняемый функтор. Если не ругаться, то это функция, которая выполняется сразу после объявления. Примеры:
1 |
(function(){ /* code */ }()); |
1 |
(function(){ /* code */ })(); |
1 |
!function(){ /* code */ }(); // facebook style |
Очень удобны тем, что не захламляют глобальное пространство переменных, могут использоваться для создания замыканий и т. д. В общем то, чем каждый день пользуешься, но вечно забываешь, как называется). Хорошая статья. …
Очередь на js
Нужно было сделать простенькую очередь, чтобы добавить много колбэков, а потом выполнить последний из очереди по таймауту, отсчитываемому от времени последнего добавления. Очередь получилась простенькая (за полчаса много и не сделаешь). Использование:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//опциональное время в милисекундах - таймаут от последнего события var queue = queueFactory( 5000 ); // у меня дёргается скрипт по определённому событию, в нём написано $( window ).bind( 'event1', function( Event, Data ) { if ( ! queue.length() ) { showLoader(); } queue.add( function() { console.log( 'event1' ); } ); } ); $( window ).bind( 'event2', function( Event, Data ) { if ( ! queue.length() ) { showLoader(); } queue.add( function() { console.log( 'event2' ); } ); } ); |
В итоге через 5 секунд после наступления последнего из событий в консоль выведется соответствующее сообщение.
jQuery.deferred
В jQuery 1.5 была полностью переработана модель асинхронных запросов. Теперь они возвращают deferred-объект, содержащий promise-объект, который содержит методы, позволяющие узнать состояние запроса или навесить дополнительные обработчики. promise-Объект содержит методы then, done, fail, isResolved и isRejected. Суть нового подхода состоит в следующем:
1 2 3 4 5 6 7 |
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){ // a1 и a2 - аргументы, отвечающие соответственно за запросы к страницам page1 и page2 var jqXHR = a1[2]; /* массив состоит из [ "success", statusText, jqXHR ] */ if ( /Оппа!/.test(jqXHR.responseText) ) { alert("Где-то на первой странице есть 'Оппа!'."); } }); |
$.when принимает deferred-объект или объекты и возвращает promise-объект. Можно делать и так:
1 2 3 4 5 6 7 8 9 10 11 12 |
var $promise; if ( tt == 1 ) { $promise = $.when( $.getJSON( ... ) ); } else if ( tt == 2 ) { $promise = $.when( $.getJSON( ... ), $.getJSON( ... ), $.post( ... ) ); } else { $promise = $.when( console.log( 'else' ) ); } $promise. then( function() { console.log( 'done', data ) } ); |
…
jQuery.delegate
jQuery.delegate и jQuery.undelegate появились в jQuery 1.4.2. Это аналоги .live и .die(). У .live и .die() есть проблемы с, к примеру, вложенными объектами, с встраиванием в цепочки и много ещё. Синтаксис .delegate отличается от .live и, соответственно, .click и т.п. Пример использования:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Using .live() $("table").each(function(){ $("td", this).live("hover", function(){ $(this).toggleClass("hover"); }); }); // Using .die() $("table").each(function(){ $("td", this).die("hover"); }); // Using .delegate() $("table").delegate("td", "hover", function(){ $(this).toggleClass("hover"); }); // Using .undelegate() $("table").undelegate("td", "hover"); |
http://api.jquery.com/delegate/ Работа с событиями в jQuery 1.7+