1
\$\begingroup\$

I would like a code review for my first simple slideToggle jQuery plugin.

Demo

(function($) {
    $.fn.ezToggle = function(options) {
        var defaults = {
                selector : '.yourSelector',
                speed :  300,
                openedClassName : 'opened',
                closedClassName : 'closed',
            }, 
        options = $.extend(defaults, options);

            return this.each(function() {

                var originalHeight = $(this).outerHeight(true);

                options.minHeight = options.minHeight || $(this).find(defaults.selector).outerHeight(true);

                if (!$(this).hasClass(defaults.openedClassName)) {
                    $(this).addClass(defaults.closedClassName).height(options.minHeight);
                }       

                $(this).find(defaults.selector).on('click', function(e) {
                    e.preventDefault();

                    var $parent = $(this).parent();

                    if ( $parent.hasClass(defaults.closedClassName) ) {

                        $('.'+defaults.openedClassName)
                            .removeClass(defaults.openedClassName)
                            .addClass(defaults.closedClassName)
                            .animate( {
                                height : options.minHeight
                            }, defaults.speed );

                        $parent.removeClass(defaults.closedClassName)
                               .addClass(defaults.openedClassName)
                               .animate({
                                   height : originalHeight
                               }, defaults.speed);

                    } else if ( $parent.hasClass(defaults.openedClassName) ) {

                        $parent.removeClass(defaults.openedClassName)
                               .addClass(defaults.closedClassName)
                               .animate({
                                   height : options.minHeight
                               }, defaults.speed);

                    }
                });

            });

    };
}) (jQuery);
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

If you didn't know already, this type of plugin is referred to as an accordion. I would suggest reading the code for the jQuery plugin (since you are using jQuery) to find out how they do it. With this you can get ideas, see their organization, and if you find something that can be fixed/improved you'll have the power to contribute!

To add to redexp's answer about the preventDefault() method. In your click functions you might want to prevent the default browser action on a link, which is to direct the page to that link. Since you just want to perform something on your page and don't actually want the browser to leave the page you should prevent that action. The difference between the two is that return false; does that and at the same time stops event propagation. Propagation being when you click on an element, it triggers an event on the element, and any events on its parent elements (because technically they were also clicked). Whether or not you need to stop propagation is up to you, so pick accordingly.

So basically:

function() {
  return false;
}

// Is the same as doing

function(e) {
  e.preventDefault();
  e.stopPropagation();
}

It's all probably a lot more complicated than this and articles like this probably explain it all a lot better.

As you progress in plugin development you should start to think about implementing design patterns. There are almost endless options of patterns you can use and some you can event make sort of a hybrid pattern. Don't feel overwhelmed with all the options pick out a couple to start with and try them out. I'd suggest the Module Pattern (another good article) since you've already sort of implemented it in this plugin. Also look at the Observer Pattern (aka Pub/Sub) it's great for dealing with custom events. This video by Jeffery Way does a great job of explaining the concept. I'd recommend you'd watch the rest of the episodes from that series as well because he does cover some good ground on plugins.

\$\endgroup\$
1
\$\begingroup\$

First of all you don't need defaults and second options can be undefined so

options = $.extend({
        selector : '.yourSelector',
        speed :  300,
        openedClassName : 'opened',
        closedClassName : 'closed',
    }, options || {});

Third don't use every time $(this), define it once and use everywhere

var $this = $(this);

var originalHeight = $this.outerHeight(true);
...

Next, instead of e.preventDefault(); just return false in the end of .on('click', function(e) {

\$\endgroup\$

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.