Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Как сделать плагин jQuery в виде объекта? (https://javascript.ru/forum/jquery/29362-kak-sdelat-plagin-jquery-v-vide-obekta.html)

SkaN 25.06.2012 13:49

Как сделать плагин jQuery в виде объекта?
 
Ну, название темы, может быть, сформулировано коряво. Но ниже подробности.
Принцип в голове таков: делается объект, к примеру:
var plugin = {
    name: "plugin",
    __init: function(){...},
    foo: function(){...}
}

Потом этот объект становится частью jQuery (не знаю, как). Гуглеж дает только начальные принципы создания плагинов.
Вобщем смысл примерно таков: хочу объект сделать частью jQuery, чтобы без самого объекта его методы и свойства нельзя было вызывать.
$("...").plugin.__init(); // Нет ошибки
$("...").__init(); // Ошибка, метод не является частью jQuery.

Вот так. Если что-то не понятно (а с моим описанием, наверняка многое не понятно), спрашивайте - объясню :)

DjDiablo 25.06.2012 16:27

(function($){
         var name="youPlug";
         $.fn[name]=function(options){
             //получим ссылку на контейнер
             var container=$(this);

             //если в контейнере это плагина нет, тогда создадим новый экземпляр

	          if (!container.data(name)){	
                    //создаём плагин
	          	    var f=function(){
                           //здесь вы можете разместить приватные функции и переменные

                          // return возвращает обьект с публичными свойствами
                          return {
                              // напишем какойнибудь демонстрационный код
                              msg:options.msg,
                              test:function(){
                                  alert(this.msg);
                              }
                          }
                     }
                     //сохраним плагин в data
                     container.data(name,f());		                
              }
              //если плагин есть, то возвращаем уже созданный экземпляр
              else {
		             return container.data(name);
              }
                     
          }
})(jQuery);

//эксперемент
$(function(){
   $("#test").youPlug({msg:"привет"}); //создаём плагин 
   $("#test").youPlug().test(); //вызываем метод плагина //alert("привет")
})

melky 25.06.2012 16:34

Цитата:

Сообщение от SkaN (Сообщение 183912)
Ну, название темы, может быть, сформулировано коряво. Но ниже подробности.
Принцип в голове таков: делается объект, к примеру:
var plugin = {
    name: "plugin",
    __init: function(){...},
    foo: function(){...}
}

Потом этот объект становится частью jQuery (не знаю, как). Гуглеж дает только начальные принципы создания плагинов.
Вобщем смысл примерно таков: хочу объект сделать частью jQuery, чтобы без самого объекта его методы и свойства нельзя было вызывать.
$("...").plugin.__init(); // Нет ошибки
$("...").__init(); // Ошибка, метод не является частью jQuery.

Вот так. Если что-то не понятно (а с моим описанием, наверняка многое не понятно), спрашивайте - объясню :)

если я правильно понял, то :
jQuery.fn.plugin = plugin;

SkaN 25.06.2012 17:14

Цитата:

Сообщение от melky (Сообщение 183949)
если я правильно понял, то :
jQuery.fn.plugin = plugin;

а как тогда в плагине держать объект jQuery?

2 DjDiablo: спасибо большое, решение развернутое и понятное :)

melky 25.06.2012 18:29

Цитата:

Сообщение от SkaN (Сообщение 183967)
а как тогда в плагине держать объект jQuery

зачем? либо я чего-то не понял (всё-таки), либо Вы имели в виду сохранить ф-ю JQ в переменной. это проще простого. после присваивания обернуть код в замыкание (см пример кода выше)

SkaN 26.06.2012 10:37

2 melky: нужно, чтобы в объекте хранился объект jQuery и потом передавался всем методам объекта. Как-то так...

SkyLight 27.06.2012 15:11

Непонятно, чем вас не устраивает официальная документация по написанию плагинов для jQuery? Она довольно подробна. Если вы хотите писать плагин, то и пишите его по существующим правилам, не надо придумывать свои.

DjDiablo 27.06.2012 17:15

Цитата:

Непонятно, чем вас не устраивает официальная документация по написанию плагинов для jQuery? Она довольно подробна. Если вы хотите писать плагин, то и пишите его по существующим правилам, не надо придумывать свои.
Я скажу с точностью наоборот.
Придумывайте свои правила, делайте нестандартно, делайте оригинально, далайте быстрее других, делайте надёжнее других, делайте мощнее чем у других, не стойте на месте, работайте на опережение.

SkyLight 27.06.2012 17:24

Это можно сказать опытному человеку, т.к. он сделает хоть и по своему, но правильно и понятно для других. А вот начинающие в таком случае понаписывают такого, что захочется им оторвать жопу...

devote 27.06.2012 19:15

Цитата:

Сообщение от DjDiablo (Сообщение 183946)
(function($){
         var name="youPlug";
         $.fn[name]=function(options){
             //получим ссылку на контейнер
             var container=$(this);
            // ...............
          }
})(jQuery);

Вообще обычно начинать плугин надо так:
(function($){
         var name="youPlug";
         $.fn[name]=function(options){

             return this.each(function() { // проходим по всем элементам
                 //получим ссылку на контейнер
                 var container=$(this);
                // ...............
             });

          }
})(jQuery);
Хотя в вашем случае будет работать и так как у вас, так как вы не юзаете свойства отдельных элементов.

melky 27.06.2012 19:19

Цитата:

Сообщение от SkaN
Потом этот объект становится частью jQuery

это делается только добавлением свойства (значением может быть объект) либо в jQuery.fn, либо в jQuery.fn.init.prototype.

насчёт второго :
<script src="http://code.jquery.com/jquery-1.7.2.js"></script>
<script>
jQuery.fn.init.prototype.foo = { bar: "ok" };
alert( $().foo.bar );
</script>


Цитата:

Сообщение от SkaN
Вобщем смысл примерно таков: хочу объект сделать частью jQuery, чтобы без самого объекта его методы и свойства нельзя было вызывать.

а как можно обратиться к методам объекта без самого объекта? :)

Цитата:

Сообщение от SkaN
2 melky: нужно, чтобы в объекте хранился объект jQuery и потом передавался всем методам объекта. Как-то так...

нужно как-то сохранять этот объект. я сделал через наследование :

<script src="http://code.jquery.com/jquery-1.7.2.js"></script>
<p>TEST</p>
<script>
jQuery.fn.colorchangers = {
    toRed: function() {
        // JQ-объект (контекст) хранится в свойстве _this
        // this - это объект, который щас описываем.
        return this._this.css("color", "red");
    },
    randomColors: ["green", "aqua", "lime"],
    toRandom: function(){
        // т.к. this равен объекту colorchangers, то может обратиться к его свойствам
        var randomColor =  this.randomColors[Math.floor(Math.random()*this.randomColors.length)];
        return this._this.css("color", randomColor);
    }
};

// тут вся магия
function createGetter(propName) {

    // упс, нет такого объекта
    if (typeof jQuery.fn[propName] != "object") {
        return $.error("Указанное имя свойства "+propName+" не является объектом");
    }

    // наследование проходится в курсе молого бойца.
    var F = function(){};
    F.prototype = jQuery.fn[propName];

    // делаем из объекта геттер.
    jQuery.fn[propName] = function() {
        // чтобы каждый раз не создавать, сохраним его.
        var fresh = this.data(propName+"_getter");

        // если не сохранён, создаём и сохраняем
        if (!fresh) {
            fresh = new F();
            this.data(propName+"_getter", fresh);
        }

        // сохраняем\изменяем контекст - в любой момент он может измениться - добавиться элементы и т.д.
        fresh._this = this;

        return fresh;
    };
}

// колдуем ... 
createGetter("colorchangers");

// тестим
var test = $("p");

test.colorchangers().toRed();
</script>
<div>TEST_2</div>
<script>
setTimeout(function() {
    // изменим объект JQ и ещё затестим
    test = test.add("div");
    test.colorchangers().toRandom();
}, 800);
</script>


Цитата:

Сообщение от DjDiablo
далайте быстрее других, делайте надёжнее других, делайте мощнее чем у других

утопия. эти понятия противоречивы.

PS послезавтра экзамен по философии. могу бредить :)

DjDiablo 27.06.2012 23:59

Devote - спасибо, перебор хоть и нужен не всегда,
но в том случае который я имел ввиду он и вправду нужен,
я забыл про него просто напросто.

melky
Это не утопия, это вроде бы как гипербола :)
в общем стилистическая фигура явного и намеренного преувеличения, имеющего целью усиление выразительности :D
Цитата:

я сделал через наследование 
жёстко завернул. :D
А не лучше ли уж тогда вместо propName, сразу обьект передавать ?
<script src="http://code.jquery.com/jquery-1.7.2.js"></script>
<p>TEST</p>
<script>
// тут вся магия (бывший метод createGetter)
jQuery.createPlugin=function (propName,obj) {

    // наследование проходится в курсе молого бойца.
    var F = function(){};
    F.prototype = obj;

    // делаем из объекта геттер.
    jQuery.fn[propName] = function() {
        // чтобы каждый раз не создавать, сохраним его.
        var fresh = this.data(propName+"_getter");

        // если не сохранён, создаём и сохраняем
        if (!fresh) {
            fresh = new F();
            this.data(propName+"_getter", fresh);
        }

        // сохраняем\изменяем контекст - в любой момент он может измениться - добавиться элементы и т.д.
        fresh._this = this;

        return fresh;
    };
}

// колдуем ... 
jQuery.createPlugin("colorchangers",{
    toRed: function() {
        // JQ-объект (контекст) хранится в свойстве _this
        // this - это объект, который щас описываем.
        return this._this.css("color", "red");
    },
    randomColors: ["green", "aqua", "lime"],
    toRandom: function(){
        // т.к. this равен объекту colorchangers, то может обратиться к его свойствам
        var randomColor =  this.randomColors[Math.floor(Math.random()*this.randomColors.length)];
        return this._this.css("color", randomColor);
    }
});

// тестим
var test = $("p");

test.colorchangers().toRed();
</script>
<div>TEST_2</div>
<script>
setTimeout(function() {
    // изменим объект JQ и ещё затестим
    test = test.add("div");
    test.colorchangers().toRandom();
}, 800);
</script>

melky 28.06.2012 12:31

Цитата:

Сообщение от DjDiablo
А не лучше ли уж тогда вместо propName, сразу обьект передавать ?

когда я стал писать код, и удалять 2 идеи, возникише до этого, как-то лень было чистить код:)


Часовой пояс GMT +3, время: 11:17.