Comments 40
Написано хорошо, но мало :)
По сути, зацеплено только самое-самое основное — еще интересно было бы почитать в таком ключе про реализацию движка селекторов, например.
По сути, зацеплено только самое-самое основное — еще интересно было бы почитать в таком ключе про реализацию движка селекторов, например.
я за то чтобы продолжить и углубиться )
UFO just landed and posted this here
console.log('He's alive!'); — дает ошибку из-за апострофа в сокращении англ. языка
«а также некий rootjQuery — объект jQuery с ссылкой на document»
rootjQuery — кэш часто встречаемого $(document). Улучшает производительность.
rootjQuery — кэш часто встречаемого $(document). Улучшает производительность.
Про DatePicker сильно удивился, потому что это все-таки UI-плагин, а они обычно пишутся по другому. Но действительно, так.
Ну, как бы там ни было, я скорее имел ввиду интерфейс — есть один статический и один динамический метод с названием плагина, который инкапсулирует в себе весь экшн.
Я прекрасно понял вашу мысль. Но вы все-таки сходите по ссылке.
Widget factory часть UI, её нет в ядре jQuery.
DateInput в самом деле не использует widget factory, но есть такие планы :)
// TODO rename to «widget» when switching to widget factory
Подход описанный TheShock в сам деле часто встречается в сторонних плагинах и мне часто доставляет проблемы когда у плагина есть замкнутые, анонимные функции, а настроек для их кастомизации нет:
var privateMethod = function () {
// private method, used for plugin
};
Приходится править исходный код плагина и получать геморрой при обновлении.
У самого jQuery можно переопределять отдельные части. Например можно делать так при отладке/поиске узкого места:
$.fn.find = console.log;
DateInput в самом деле не использует widget factory, но есть такие планы :)
// TODO rename to «widget» when switching to widget factory
Подход описанный TheShock в сам деле часто встречается в сторонних плагинах и мне часто доставляет проблемы когда у плагина есть замкнутые, анонимные функции, а настроек для их кастомизации нет:
var privateMethod = function () {
// private method, used for plugin
};
Приходится править исходный код плагина и получать геморрой при обновлении.
У самого jQuery можно переопределять отдельные части. Например можно делать так при отладке/поиске узкого места:
$.fn.find = console.log;
Упс, не туда ответил. habrahabr.ru/blogs/jquery/118564/#comment_3866364 — это вам.
> Приходится править исходный код плагина и получать геморрой при обновлении.
Увы, увы, mankey patching — это всегда плохо, но иногда без него никак.
Вообще, найти хорошо написанный плагин довольно трудно:(
> У самого jQuery можно переопределять отдельные части.
Естественно, это ж JS:)
Увы, увы, mankey patching — это всегда плохо, но иногда без него никак.
Вообще, найти хорошо написанный плагин довольно трудно:(
> У самого jQuery можно переопределять отдельные части.
Естественно, это ж JS:)
Если вдруг кто-то не видел, есть два прекрасных видео в тему от Poul Irish: paulirish.com/2010/10-things-i-learned-from-the-jquery-source/ и paulirish.com/2011/11-more-things-i-learned-from-the-jquery-source/
А мне вот нифига не понятно, зачем вот тут в начале
new
.new function (document, $, undefined) {
var privateMethod = function () {
// private method, used for plugin
};
$.fn.myPlugin = function () {
};
// и, если нужен метод, не привязанный к dom-элементам:
$.myPlugin = function () {
};
}(document, jQuery);</script>
Если только для того, чтобы скобки лишние не ставить, то это явно abusing языковых конструкций. Плюс, проще, короче и понятнее написать так:
<source lang="javascript">
!function(){ console.log('hello world'); }();
www.keyframesandcode.com/resources/javascript/deconstructed/jquery/ — удобно, чтобы долго не лазить по длинному коду, только там 1.4.2
Наилучший шаблон для небольших плагиновjQuery Plugin Boilerplate — полная версия с коментами, ниже сокращенная
(function($) {
$.fn.pluginName = function(method) {
var defaults = {
foo: 'bar'
}
var settings = {}
var methods = {
init : function(options) {
settings = $.extend({}, defaults, options)
return this.each(function() {
var
$element = $(this),
element = this;
// code goes here
});
},
foo_public_method: function() {
// code goes here
}
}
var helpers = {
foo_private_method: function() {
// code goes here
}
}
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method "' + method + '" does not exist in pluginName plugin!');
}
}
})(jQuery);
автор — John Resig, aka jeresig, известный гуру и евангелист Javascript в Mozilla Corporation
Уже бывший евангелист Mozilla.
Да, я знаю, спасибо. Ждал завершения перевода, чтобы исправить.
Функция init возвращает объект согласно селектору. Каким образом функция-плагин попадает в этот объект при её добавлении к прототипу самого jQuery? Допустим я пишу $.fn.foo = function(){ // some code }, как получается так, что когда я вызываю $('element').foo(), она запускается?
Я взял куски кода из Вашей статьи. Они прекрасно работают для встроенных фукнций объекта. К примеру, если element — это div, то спокойно можно получить $('element').innerHTML. Но про «плугин» мне говорят, что «Uncaught TypeError: Object #HTMLDivElement has no method 'foo'», и привет.
Чего я не понял?
Я взял куски кода из Вашей статьи. Они прекрасно работают для встроенных фукнций объекта. К примеру, если element — это div, то спокойно можно получить $('element').innerHTML. Но про «плугин» мне говорят, что «Uncaught TypeError: Object #HTMLDivElement has no method 'foo'», и привет.
Чего я не понял?
По сути вы расширяете прототип новым методом. А все объекты, которые созданы при помощи $ — как раз имеют ссылку на этот прототип.
Второе не совсем понял. По идее, должно работать вполне предсказуемо.
Второе не совсем понял. По идее, должно работать вполне предсказуемо.
Ну вот что у меня получилось:
В итоге мне сообщают, что функции foo нету. Хотя $('qwe') — корректный HTMLDivElement со всеми пирогами.
То есть добавление функции foo() в $.fn ничего не расширяет…
Или на меня напал адский тупак?
(function(window, undefined) {
var document = window.document;
var jQuery = (function() {
var jQuery = function(selector, context, undefined) {
return new jQuery.fn.init(selector, context);
};
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function(selector, context, undefined) {
if (!selector) return this;
return typeof(selector) === 'string' ?
document.getElementById(selector) : selector;
}
};
jQuery.fn.init.prototype = jQuery.fn;
return jQuery;
})();
window.jQuery = window.$ = jQuery;
})(window);
// Plugin
(function($) {
$.fn.foo = function() {
console.log('bar');
}
})(jQuery);
// <div id="qwe">asd</div>
$('qwe').foo();
В итоге мне сообщают, что функции foo нету. Хотя $('qwe') — корректный HTMLDivElement со всеми пирогами.
То есть добавление функции foo() в $.fn ничего не расширяет…
Или на меня напал адский тупак?
return typeof(selector) === 'string' ? document.getElementById(selector) : selector;
Тут возвращается нативный дом-элемент, а должен возвращаться инстанс конструктора
jQuery.fn.init
И то правда…
init: function(selector, context, undefined) {
if (!selector) return this;
if(typeof(selector) === 'string') {
this[0] = document.getElementById(selector);
this.selector = selector;
this.context = context;
return this;
} else {
this.context = this[0] = selector;
return this;
}
}
Вот как-то так. Хорошо бы это отразить в статье, а то чайники вроде меня кипят :)
Sign up to leave a comment.
Как устроен jQuery: изучаем исходники