4
\$\begingroup\$

I would like to know if I'm writing a plugin for jquery correctly. I followed the official guide and also added some tweaks that I've found from various sources over time.

While this works perfectly, I don't know if I'm doing something wrong.

This is the sample:

(function($)
{
    var plugin = "my_plugin_name";
    var methods = {
        init : function(user_settings)
        {
            return this.each(function(index)
            {
                if(!$(this).hasClass("plugin_class"))
                {
                    $(this).addClass("plugin_class");

                    var $this = $(this);
                    var data = $this.data(plugin);

                    if(!data)
                    {
                        var default_settings = {
                            optionA: "abc",
                            optionB: 123,
                            optionB: true
                        };

                        if(user_settings)
                        {
                            $.extend(true, default_settings, user_settings);
                        }

                        $this.data(plugin,
                        {
                            "settings": default_settings
                        });
                    }

                    privateMethod($this);
                }
           });
        },
        exposedMethodX : function(value) //$(selector).my_plugin_name("exposedMethodX", true)
        {
            console.log(value)
        }
    };

    $.fn[plugin] = function(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
        {
            alert("Method " +  method + " does not exist");
        }
    };

    function privateMethod(obj)
    {
        console.log(obj.data(plugin).settings);
    }
})(jQuery);
\$\endgroup\$
4

2 Answers 2

2
\$\begingroup\$

From a short review;

  • Please follow the lowerCamelCase naming convention, user_settings -> userSettings
  • In production code, never use console.log or alert
  • You set optionB twice

            var default_settings = {
                optionA: "abc",
                optionB: 123,
                optionB: true
            };
    
  • The cyclomatic complexity would be lower if you exit immediately after the hasClass check:

            if($(this).hasClass("plugin_class")){
                return;
            }
    
  • You could even consider using filter on hasClass instead of checking for each

  • "plugin_class" should be a constant right under var plugin

  • The following

            if(user_settings)
            {
                $.extend(true, default_settings, user_settings);
            }
    

    could be written as

            $.extend(true, user_settings || default_settings);
    
\$\endgroup\$
2
+25
\$\begingroup\$

In general the template looks like a good start. I noticed that the code appears to resemble the format advised in PHP-Fig's PSR-2, namely "The opening brace MUST go on its own line"1 for functions and methods plus control structures like if and else blocks. Most of the Javascript style guides I have seen call for curly braces to exist on the same line of the block they are opening. Personally I don't even agree with this in PHP, let alone Javascript, however if that is your personal preference then keep it consistent.


Inside the init method, there is an iterator:

return this.each(function(index)
{
    if(!$(this).hasClass("plugin_class"))
    {
        $(this).addClass("plugin_class");

       var $this = $(this);

The reference var $this = $(this); could be stored before the check of the class name and/or class name addition in order to reduce DOM queries.

Also, the name $this could be more descriptive - at least something like $element or $elem (as shown in the example under Provide Public Access to Secondary Functions as Applicable from the Advanced Plugin Concepts).

Addressing Your Additional question

You asked in a comment:

what about the $.fn[plugin] part? I'm not sure about the first if statement. could that function be refactored and improved?

It is possible that features like the spread syntax could potentially be used to simplify the call, though given that current jQuery browser support includes IE 9+ it may not be wise to utilize ES-6 features.

\$\endgroup\$
2
  • \$\begingroup\$ thanks for your feedback. what about the $.fn[plugin] part? I'm not sure about the first if statement. could that function be refactored and improved? \$\endgroup\$ Jul 8, 2019 at 20:39
  • \$\begingroup\$ I expanded my answer to address your question \$\endgroup\$ Jul 9, 2019 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.