改写jQuery UI的Accordion

最近在做一个项目,其中有个UI要做成类似jQuery UI中Accordion的样子。但是Accordion在某一时刻只可以展开一个Panel,所以就改写了一下Accordion,让它可以同时展开多个Panel。

源代码:

(function($) {
    if ($.ui.accordion) {
        var old_clickHandler = $.ui.accordion.prototype._clickHandler;
        var new_clickHandler = function(event, target) {
            var o = this.options;
            if (o.disabled) return false;
            // called only when using activate(false) to close all parts programmatically
            if (!event.target && o.collapsible) {
                this.headers.removeClass("ui-state-active ui-corner-top")
                            .addClass("ui-state-default ui-corner-all")
                            .find(".ui-icon")
                            .removeClass(o.icons.headerSelected)
                            .addClass(o.icons.header);
                this.headers.next().addClass('ui-accordion-content-active');
                var toHide = this.headers.next(),
                            data = {
                                options: o,
                                newHeader: $([]),
                                oldHeader: o.headers,
                                newContent: $([]),
                                oldContent: toHide
                            },
                            toShow = (this.active = $([]));
                this._toggle(toShow, toHide, data);
                return false;
            }
            // get the click target
            var clicked = $(event.currentTarget || target);
            var clickedIsActive = clicked.next().css("display") != "none";
            // if animations are still active, or the active header is the target, ignore click
            if (this.running || (!o.collapsible && clickedIsActive)) {
                return false;
            }

            // switch classes
            clicked.toggleClass("ui-state-active")
                        .toggleClass("ui-corner-top")
                        .toggleClass("ui-state-default")
                        .toggleClass("ui-corner-all")
                        .find(".ui-icon")
                        .toggleClass(o.icons.headerSelected)
                        .toggleClass(o.icons.header);
            clicked.next().addClass('ui-accordion-content-active');

            // find elements to show and hide
            var toShow = clicked.next(),
                        toHide = clickedIsActive ? clicked.next() : $([]),
                        data = {
                            options: o,
                            newHeader: clickedIsActive && o.collapsible ? $([]) : clicked,
                            oldHeader: $([]),
                            newContent: clickedIsActive && o.collapsible ? $([]) : toShow.find('> *'),
                            oldContent: $([])
                        },
                        down = true;

            this._toggle(toShow, toHide, data, clickedIsActive, down);

            return false;
        };

        $.extend($.ui.accordion.defaults, {
            collapsible: true,
            multipleMode: false
        });

        $.extend($.ui.accordion.prototype, {
            _clickHandler: function(event, target) {
                if (this.options.multipleMode === true) {
                    new_clickHandler.apply(this, arguments);
                }
                else {
                    old_clickHandler.apply(this, arguments);
                }
            }
        });
    };
})(jQuery);

将上面的代码保存成.js文件并引入到页面,调用的时候只要设置multipleMode为true就可以了。

$("#accordion").accordion({multipleMode: true});

改写jQuery UI的Accordion》上有9条评论

  1. 郭猛

    你好,你这个写的不错,我也需要这个功能,但是我在使用这个mutiMode属性的时候发现有一个问题,在我打开或者关闭任何一个panel的时候,页面总是自动设置第一个panel的头在顶端。请问您有没有解决这个问题的方法,谢谢!

  2. 小寒 文章作者

    这个是我乱猜的,我现在还在休假,等回去的时候再看看.你如果有例子的话,请发到coldstars(at)msn.com这个邮箱里吧,谢谢关注.

  3. 郭猛

    小寒你好,还是我,问题已经解决了。你的重写没问题,确实是你在2月23日说的那个原因,我没有注意到,我用A标签作了panel的head,href值设置成了#,除了问题我没有检查我的源码,而是一直在jquery里面找,这实在是个愚蠢的错误。谢谢你的回复!

  4. 郭猛

    小寒你好,我又遇到新问题过来跟你讨论,我在用accordion的时候,其中有一个panel里面是个IFRAME,在我每次点击打开这个panel的时候总是要隔几秒钟才会显示出来,而我在panel里面直接输出文本就没有问题,对于这个问题你有没有好的意见:我的代码大概这是这样,你可以测试一下

    TITLE

    <-问题就在这里,每次打开都要等一会显示内容。

    TITLE

    sometext

  5. 小寒 文章作者

    你好,这个问题我也发现了,不过没有什么好办法去解决。我跟踪了一下,应该是jQuery底层的实现比较慢。

发表评论