Pull to refresh

Comments 40

Написано хорошо, но мало :)

По сути, зацеплено только самое-самое основное — еще интересно было бы почитать в таком ключе про реализацию движка селекторов, например.
Ну я старался не перегрузить статью. И так статья вышла достаточно объемной. Можно будет продолжить)
Большое спасибо! Думаю, greedykid ожидал толстый мануал о том, как стать членом jQuery Core Team.=)
Движок селекторов, это уже библиотека Sizzle, которую jquery позаимствовала.
согласен, хорошая статья… тоже хочу углубится… и в другие фреймворки тоже углубится!)
UFO just landed and posted this here
Простите, при чём тут весна? В топике даже сисек нету.
UFO just landed and posted this here
UFO just landed and posted this here
console.log('He's alive!'); — дает ошибку из-за апострофа в сокращении англ. языка
«а также некий rootjQuery — объект jQuery с ссылкой на 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;
> Приходится править исходный код плагина и получать геморрой при обновлении.
Увы, увы, mankey patching — это всегда плохо, но иногда без него никак.
Вообще, найти хорошо написанный плагин довольно трудно:(

> У самого jQuery можно переопределять отдельные части.
Естественно, это ж JS:)
А мне вот нифига не понятно, зачем вот тут в начале 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'); }();
ага, кнопка «предпросмотр» типа для лохов.
Такая запись в моей IDE отмечается как ошибка, потому как-то стараюсь её избегать) А через круглые скобки надо ставить ещё и точку с запятой в начало.
Наилучший шаблон для небольших плагинов
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);
Тогда надо написать скрипт, который создаёт такие вещи.
И, как я понял, $.widget и есть такой скрипт)

PS. А зачем приватные переменные создаются каждый раз при вызове функции?
автор — 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'», и привет.

Чего я не понял?
По сути вы расширяете прототип новым методом. А все объекты, которые созданы при помощи $ — как раз имеют ссылку на этот прототип.
Второе не совсем понял. По идее, должно работать вполне предсказуемо.
Ну вот что у меня получилось:

(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.

Articles