jQuery UI 选项卡插件损坏

标签 jquery jquery-ui jquery-plugins jquery-ui-tabs

我们正在使用这个 fiddle 中的 jquery ui tabs arrow 插件:http://jsfiddle.net/dECtZ/282/ ,但像许多插件一样,它与最新版本的 jQuery 不同。我们能够让 csscur 工作,但在 jquery 核心中仍然出现以下错误(第 353 行):

未捕获的类型错误:无法分配给函数 (e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)} 的只读属性“length”

代码如下:

(function($, undefined) {
    if (!$.xui) {
        $.xui = {};
    }
    var tabs = $.extend({}, $.ui.tabs.prototype),
        _super = {
            _create: tabs._create,
            _destroy: tabs._destroy,
            _update: tabs._update
        };
    $.xui.tabs = $.extend(tabs, {
        options: $.extend({}, tabs.options, {
            scrollable: false,
            changeOnScroll: false,
            closable: false,
            resizable: false,
            resizeHandles: "e,s,se"
        }),
        _create: function() {
            var self = this,
                o = self.options;
            _super._create.apply(self);
            if (o.scrollable) {
                self.element.addClass("ui-tabs-scrollable");
                var scrollContainer = $('<div class="ui-tabs-scroll-container"></div>').prependTo(this.element);
                self.header = $('<div class="ui-tabs-nav-scrollable ui-widget-header ui-corner-all"></div>').prependTo(scrollContainer);
                var nav = self.element.find(".ui-tabs-nav:first").removeClass("ui-widget-header ui-corner-all").appendTo(this.header);
                var arrowsNav = $('<ol class="ui-helper-reset ui-helper-clearfix ui-tabs-nav-arrows"></ol>').prependTo(self.element);
                var navPrev = $('<li class="ui-tabs-arrow-previous ui-state-default ui-corner-bl ui-corner-tl" title="Previous"><a href="#"><span class="ui-icon ui-icon-carat-1-w">Previous tab</span></a></li>').prependTo(arrowsNav).hide(),
                    navNext = $('<li class="ui-tabs-arrow-next ui-state-default ui-corner-tr ui-corner-br" title="Next"><a href="#"><span class="ui-icon ui-icon-carat-1-e">Next tab</span></a></li>').appendTo(arrowsNav).hide();


                var scrollTo = function(to, delay) {
                    var navWidth = 0,
                        arrowWidth = navPrev.outerWidth(),
                        marginLeft = -(parseInt(nav.css("marginLeft"), 10)),
                        hwidth = self.header.width(),
                        newMargin = 0;

                    nav.find("li").each(function() {
                        navWidth += $(this).outerWidth(true);
                    });

                    if (to instanceof $.Event) {

                    } else {
                        newMargin = marginLeft+to;
                        if (newMargin > (navWidth-hwidth)) {
                            newMargin = (navWidth-hwidth);
                        } else if (newMargin < 0) {
                            newMargin = 0;
                        }
                        nav.stop(true).animate({
                            marginLeft: -(newMargin)
                        }, delay, function(){
                            $(window).trigger("resize.tabs");
                        });
                    }
                }


                var holdTimer = false;
                navPrev.add(navNext).bind({
                    "click": function(e) {
                        var isNext = this === navNext[0];
                        e.preventDefault();
                        if (o.changeOnScroll) {
                            self.select(self.options.selected + (isNext ? 1 : -1));
                        } else {
                            if (!holdTimer)
                                scrollTo(isNext ? 150 : -150, 250);
                        }
                    },
                    "mousedown": function(e){
                        if (!o.changeOnScroll) {
                            var isNext = this === navNext[0],
                                duration = 10, pos = 15, timer;
                            if (holdTimer)
                                clearTimeout(holdTimer);
                            holdTimer = setTimeout(timer = function(){
                                scrollTo(isNext ? pos : -(pos), duration);
                                holdTimer = setTimeout(arguments.callee, duration);
                            }, 150);
                        }
                    },
                    "mouseup mouseout": function(e){
                        if (!o.changeOnScroll) {
                            clearTimeout(holdTimer);
                            holdTimer = false;
                            nav.stop();
                        }
                    }
                });

                self.header.bind('mousewheel', function(e, d, dX, dY) {
                    e.preventDefault();
                    if (d === -1) {
                        navNext.click();
                    } else if (d === 1) {
                        navPrev.click();
                    }
                });

                $(window).bind("resize.tabs", function(e) {
                    var navWidth = 0;
                    var arrowWidth = navPrev.outerWidth();
                    nav.find("li").each(function() {
                        navWidth += $(this).outerWidth(true);
                    });

                    var marginLeft = -(parseInt(nav.css("marginLeft"), 10)),
                        hwidth = self.header.width();

                    if (navWidth > (hwidth+marginLeft)) {
                        self.header.addClass("ui-tabs-arrow-r");
                        navNext.show("fade");
                        if (marginLeft > 0) {
                            self.header.addClass("ui-tabs-arrow-l");
                            navPrev.show("fade");
                        } else {
                            self.header.removeClass("ui-tabs-arrow-l");
                            navPrev.hide("fade");
                        }
                    } else {
                        self.header.removeClass("ui-tabs-arrows ui-tabs-arrow-l");
                        navNext.hide("fade");
                        if (marginLeft > 0) {
                            self.header.addClass("ui-tabs-arrow-l");
                            navPrev.show("fade");
                        } else {
                            self.header.removeClass("ui-tabs-arrow-l");
                            navPrev.hide("fade");
                        }
                    }
                }).trigger("resize.tabs");

                arrowsNav.find("li").bind({
                    "mouseenter focus": function(e) {
                        $(this).addClass("ui-state-hover");
                    },
                    "mouseleave blur": function(e) {
                        $(this).removeClass("ui-state-hover");
                    }
                });

                this.anchors.bind("click.tabs", function(){
                    var li = $(this).parent(),
                        arrowWidth = navPrev.outerWidth(),
                        width = li.outerWidth(true),
                        hwidth = self.header.width(),
                        pos = li.position().left,
                        marginLeft = -(parseInt(nav.stop(true,true).css("marginLeft"),10)),
                        newMargin = -1;

                    if (li.index() === 0) {
                        newMargin = 0;
                    } else if ((pos+width) >= (hwidth+marginLeft)) {
                        newMargin = pos-hwidth+width;
                        if ((li.index()+1) < nav.find("li").length) {
                            newMargin += arrowWidth;
                        }
                    } else if (pos < marginLeft) {
                        newMargin = pos-arrowWidth;
                    }

                    if (newMargin > -1) {
                        nav.animate({
                            marginLeft: -(newMargin)
                        }, 250, function(){
                            $(window).trigger("resize.tabs");
                        });
                    }
                });
            }
            return self;
        },
        _update: function(){
            console.log(arguments);
            _super._update.apply(this);
        }
    });
    $.widget("xui.tabs", $.xui.tabs);
})(jQuery);
$(function() {
    $("#tabs").tabs({
        scrollable: true,
        changeOnScroll: false,
        closable: true
    });
    $("#switcher").themeswitcher();
});

最佳答案

我在 jquery-ui 1.10.3 和 jquery-ui-1.9.2 中找到了解决方法。 JQuery 本身的版本似乎没有什么区别。

所以,在 jquery-ui-1.10.3.custom.js 的第 427 行

$.each(existingConstructor._childConstructors, function( i, child ) {

失败,因为 _childConstructors 未使用此扩展定义。

我已经解决了这个问题

在 .each 之前添加检查以查看现有Constructor._childConstructors 是否未定义

原版

    if ( existingConstructor ) {
            $.each( existingConstructor._childConstructors, function( i, child ) {
                    var childPrototype = child.prototype;

                    // redefine the child widget using the same prototype that was
                    // originally used, but inherit from the new version of the base
                    $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
            });
            // remove the list of existing child constructors from the old constructor
            // so the old child constructors can be garbage collected
            delete existingConstructor._childConstructors;
    } else {
            base._childConstructors.push( constructor );
    }

以便其中的代码读取

    if ( existingConstructor ) {
        if (!(typeof existingConstructor._childConstructors === 'undefined')) {
            $.each( existingConstructor._childConstructors, function( i, child ) {
                    var childPrototype = child.prototype;

                    // redefine the child widget using the same prototype that was
                    // originally used, but inherit from the new version of the base
                    $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
            });
            // remove the list of existing child constructors from the old constructor
            // so the old child constructors can be garbage collected
            delete existingConstructor._childConstructors;
        }
    } else {
            base._childConstructors.push( constructor );
    }

这不是最好的解决方法,但它确实适用于 jquery-ui-1.9.2 和 jquery-ui-1.10.3 以及我最近尝试过的所有 jquery.js。

在jquery-ui-1.9.2.custom.js中,行数约为460

关于jQuery UI 选项卡插件损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13427834/

相关文章:

jquery - fancybox 3 添加缩略图标题

javascript - JQueryUI Accordion 式重新设计

jquery-plugins - 可访问的,适合移动设备的灯箱?

php - 如何将数据发布为数组的索引数组(不指定索引)

jquery - 数据表内联问题,我想在一行中显示所有操作。请看图片

JavaScript 测试 url 是否不包含某些文本

javascript - 如何将当前和明年添加到 jsDatePick 参数?

jquery-ui - 如何将标记添加到 jQuery UI slider ?

jquery - 离开字段后取消自动完成

jquery - 将工具提示应用于每个单元格