Написание плагина jQuery
Добрый день.
Нужна помощь в написании плагина. Посмотрел интернет на эту тему - на всех сайтах одна и та же статья, слизанная друг у друга. Проблема в том, что не получается передать в плагин ни опции, ни название метода, который хочу использовать. Внутри их просто не видно. Вот кусок кода (взят из статьи - но, раз не работает, значит написали брехню):
jQuery.fn.formValidation = function(options)
{
var settings =
{
fields: {
name: "name",
surname: "surname",
middlename: "middlename",
phoneNumber: "phoneNumber",
zipCode: "zipCode",
city: "city",
address: "address",
email: "email",
password1: "password1",
password2: "password2"
},
other: [], //[name, regExp, текст, положение tooltip]
tooltipPosition: "right"
};
...//всякие приватные функции...
var methods = {
init: function(options)
{
alert(options); //выдает 0
settings = jQuery.extend({}, settings, options);
//тут идет код
},
validate: function()
{
alert(22222222222);
},
isEmpty: function()
{
alert(111111111111);
}
};
var make = function(method)
{
alert(method);
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 + ' не существует для jQuery.formValidation');
}
};
return this.each(make);
};
})(jQuery);
У меня стоит, как видно alert(method), чтобы посмотреть, что передано. Так вот он всегда пишет цифру 0 - даже если в аргументе стоит какая строка с названием. В общем, как нужно написать, чтобы заработало? |
xmlns,
:write:
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
jQuery.fn.formValidation = function(options)
{
var settings =
{
fields: {
name: "name",
surname: "surname",
middlename: "middlename",
phoneNumber: "phoneNumber",
zipCode: "zipCode",
city: "city",
address: "address",
email: "email",
password1: "password1",
password2: "password2"
},
other: [], //[name, regExp, текст, положение tooltip]
tooltipPosition: "right"
};
//всякие приватные функции...
var methods = {
init: function(options)
{
alert(options.name); //выдает 0
settings = jQuery.extend(settings, options);
//тут идет код
},
validate: function()
{
alert(22222222222);
},
isEmpty: function()
{
alert(111111111111);
}
};
var make = function(method)
{
alert(method);
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 + ' не существует для jQuery.formValidation');
}
};
return this.each(function ()
{
make('init', options)
});
}
$({}).formValidation({name: "test"})
</script>
</head>
<body>
</body>
</html>
|
Спасибо, сделал наподобие Вашего кода, вроде работает:
function initialize(method)
{
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, Array.prototype.slice.call( arguments, 1 ));
}
else {
$.error('Метод с именем ' + method + ' не существует для jQuery.formValidation');
}
};
return this.each(function()
{
initialize(options); // зачем писать 'init'? А другие методы?
});
Хм, в С++ объукты проще делать, прозрачнее=) Только вот вопрос: не получается расширить переданные опции... Их снова не видно. Что нужно исправить? PS А если все же написать 'init', то вместо замены старого свойства - новым, который передали, то они оба почему-то видны...
settings = jQuery.extend(settings, options);
for(var key in settings)
{
alert(settings[key] + ' ' + key);
}
|
xmlns,
убрать 14 и часть 25 строки или передавать новый fields полностью -- {name: "test"} было просто для примера. |
Убрать объект fields? Ну а нафига тогда настройки по-умолчанию сделали? Нет, а как в других плагинах делают, когда нужно передать объект в объекте?
Короче, промаявшись в опциями, а понял, что ничего нормально не работает из-за тупой передачи данных в методы плагина. Переписал, но все равно не работает, не передаются опции.
if(methods[method])
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
else if(typeof method === 'object')
return methods.init.apply(this, method);
else if(!method)
return methods.init.apply(this, {});
else
$.error('Метод с именем ' + method + ' не существует для jQuery.formValidation');
Если тут сделать alert(method), то браузер покажет следующее, в зависимости от переданных параметров:
initialize('someMethod', options) //Выведит: someMethod
initialize('someMethod') //Выведит: someMethod
initialize(options) //Выведит: [Object] object
Казалось бы, вот - передаем так initialize(options) - в метод init передастся объект с настройками. А мы видим, когда сделаем alert(options) в:
init: function(options)
{
settings = jQuery.extend(settings, options);
alert(options);
...
}
Мы увидим undefined! Что за хрень? Объясните и покажите кто-нибудь, как передавать названия методов и настроек в плагин?! |
После долгих мучений плагин родил то, что нужно:
function initialize(method)
{
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 + ' не существует для jQuery.formValidation');
}
};
return this.each(function()
{
initialize(options);
});
|
xmlns,
methods.init.call а не methods.init.apply -- options это один аргумент а не массив -- хоть и обьект для 5 поста |
Учту.
Сейчас другая проблема: Передал в плагин настройки (метод init) - все хорошо, видны.
$('#authorizationForm').formValidation(
{
tooltipPosition: "left",
fields: {email: 'email'},
other: [['input[name=password]','','','left']]
});
После этого вызываю другой метод:
$('#authorizationForm').formValidation('isEmpty');
В этом методе использую объект настроек settings, который расширился тем, что я передал в начале:
for(var key in settings)
{
alert(key+': '+settings[key]);
}
И вижу настройки по умолчанию (см. первый пост), а не то, что я передал. Хотя в методе init, если просмотреть все через alert() - настройки расширены. А тут нет... Мистика. Как заставить плагин сохранять настройки, переданные при инициализации, от вызова к вызову? |
Цитата:
|
Если несложно, можете показать код, как это делать?
И два вопроса попутно: 1. Так делают разработчики плагинов? 2. data - это объект, вшитый в JS как его часть? |
Цитата:
|
|
Главу из книжки прочел, но про даты там ничего. А это завтра прочитаю, сейчас уже лень.
Да, с data вроде сохраняются настройки. Но вот опять палка в колеса: на странице есть два элемента: #authorizationForm и #registrationForm. Делаю следующее:
$('#authorizationForm').formValidation(
{
tooltipPosition: "left",
fields: {email: 'email'},
other: [['input[name=password]','','','left']]
});
$('#registrationForm').formValidation();
Согласно отладочной печати сначала инициализируется элемент '#authorizationForm, а за ним следом #registrationForm. Он, как видно, без параметров. Как я делаю сохранение настроек:
$(this).data('settings', settings);
Как их считываю:
var qq = $(this).data('settings'); alert(qq.other);
Вместо того, чтобы у элемента #authorizationForm эти настройки восстановились - они снова становятся исходными. Методом пристального вглядывания обнаружилось, что эти настройки непонятно почему затираются при инициализации второго элемента (#registrationForm). А он, как я говорил, идет без настроек. Собственно, а как сделать чтобы работало? PS ...В нормальных языках программирования для подобных вещей используют ООП... |
Нашел решение:
var formId = this.attr('id');
$(formId).data('settings', settings);
var qq = $(formId).data('settings');
А вот если элемент (пусть называется #elem), к которому прицеплен плагин удаляется со страницы (метод remove()), а затем вставляется через php обратно с тем же ИД, в тоже место страницы - функция data() уже не возвращает сохраненные настройки для этого элемента. Она возвращает undefined. Я так понимаю, эта функция по каким-то своим неведомым меткам определяет тот ли это элемент или другой. А как заставить его считать, что это именно тот элемент? |
xmlns,
никак -- новый элемент почему он должен знать что-то про свойства старого? либо при удалении или замене перезаписывать свойства либо хранить например в родителе элемента. |
делать привязку через делегирование -- метод on в квери.
|
Жаль, я думал, что если у элемента идентификатор прежний, значит должно все сохраниться.
|
помогите решить проблему с плагином
Здравствуйте. Сделал плагин анимированного сворачивания/разворачивания текстовых блоков. Все бы хорошо, но при наличии нескольких таких блоков параметр max-height берется с последнего блока, и если некоторые из предыдущих будут больше то раскрываются не полностью, а если меньше то анимация происходит с небольшой задержкой
(function($) {
$.fn.openhide=function(options){
var settings=$.extend({
'maxH':200,
'time':500,
'removeButton':0,
'hoverClass':false,
},options)
this.each(function(i){
hg=$(this).height()
if(hg>options.maxH){
$(this).css({
'max-height':options.maxH+'px',
'overflow-y':'hidden'
}).wrap("<div class='wrapper'></div>")
$(this).parents(".wrapper").append("<span class='opener'>Раскрыть</span>")
$(this).parents(".wrapper").find(".opener").click(function(){
opener=$(this)
div=opener.parents(".wrapper").find("div")
op=div.hasClass("opened")
div.animate({
'max-height':(op?options.maxH:hg)+'px'
},options.time,function(){
if(options.removeButton)
opener.remove()
else{
if(op){
div.removeClass("opened")
opener.text("Раскрыть")
}
else{
div.addClass("opened")
opener.text("Свернуть")
}
}
})
})
.mouseover(function(){
if(options.hoverClass)
$(this).addClass(options.hoverClass)
})
.mouseout(function(){
if(options.hoverClass)
$(this).removeClass(options.hoverClass)
})
}
})
}
})(jQuery)
опция removeButton - удаление кнопки после разворачивания |
axmed2004,
делайте замыкание параметра hg или вычисляйте истинный размер при клике ... да var незабывайте |
| Часовой пояс GMT +3, время: 21:52. |