部分刷新后 UIkit 选项卡和切换器不起作用

UIkit tabs and switcher do not work after partial refresh

好的,这有点特别。我们在我们的 XPages 应用程序中使用 UIkit。我们还使用选项卡和切换器组件 (http://getuikit.com/docs/tab.html and http://getuikit.com/docs/switcher.html)。 在我们对页面进行部分刷新之前,它们工作正常。原因是这些组件在页面加载后只初始化一次。这直接发生在我们绑定到页面的库中——没有自己的初始化脚本等。 刷新后我必须重新初始化整个东西 - 但我不熟悉语法甚至可能性。 不过,我搜索了 UIkit 库,发现了类似这样的内容:

(function(UI) {

"use strict";

UI.component('tab', {

    defaults: {
        'target'    : '>li:not(.uk-tab-responsive, .uk-disabled)',
        'connect'   : false,
        'active'    : 0,
        'animation' : false,
        'duration'  : 200
    },

    boot: function() {

        // init code
        UI.ready(function(context) {

            UI.$("[data-uk-tab]", context).each(function() {

                var tab = UI.$(this);

                if (!tab.data("tab")) {
                    var obj = UI.tab(tab, UI.Utils.options(tab.attr("data-uk-tab")));
                }
            });
        });
    },

    init: function() {

        var $this = this;

        this.current = false;

        this.on("click.uikit.tab", this.options.target, function(e) {

            e.preventDefault();

            if ($this.switcher && $this.switcher.animating) {
                return;
            }

            var current = $this.find($this.options.target).not(this);

            current.removeClass("uk-active").blur();

            $this.trigger("change.uk.tab", [UI.$(this).addClass("uk-active"), $this.current]);

            $this.current = UI.$(this);

            // Update ARIA
            if (!$this.options.connect) {
                current.attr('aria-expanded', 'false');
                UI.$(this).attr('aria-expanded', 'true');
            }
        });

        if (this.options.connect) {
            this.connect = UI.$(this.options.connect);
        }

        // init responsive tab
        this.responsivetab = UI.$('<li class="uk-tab-responsive uk-active"><a></a></li>').append('<div class="uk-dropdown uk-dropdown-small"><ul class="uk-nav uk-nav-dropdown"></ul><div>');

        this.responsivetab.dropdown = this.responsivetab.find('.uk-dropdown');
        this.responsivetab.lst      = this.responsivetab.dropdown.find('ul');
        this.responsivetab.caption  = this.responsivetab.find('a:first');

        if (this.element.hasClass("uk-tab-bottom")) this.responsivetab.dropdown.addClass("uk-dropdown-up");

        // handle click
        this.responsivetab.lst.on('click.uikit.tab', 'a', function(e) {

            e.preventDefault();
            e.stopPropagation();

            var link = UI.$(this);

            $this.element.children('li:not(.uk-tab-responsive)').eq(link.data('index')).trigger('click');
        });

        this.on('show.uk.switcher change.uk.tab', function(e, tab) {
            $this.responsivetab.caption.html(tab.text());
        });

        this.element.append(this.responsivetab);

        // init UIkit components
        if (this.options.connect) {
            this.switcher = UI.switcher(this.element, {
                "toggle"    : ">li:not(.uk-tab-responsive)",
                "connect"   : this.options.connect,
                "active"    : this.options.active,
                "animation" : this.options.animation,
                "duration"  : this.options.duration
            });
        }

        UI.dropdown(this.responsivetab, {"mode": "click"});

        // init
        $this.trigger("change.uk.tab", [this.element.find(this.options.target).filter('.uk-active')]);

        this.check();

        UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){
            if ($this.element.is(":visible"))  $this.check();
        }, 100));

        this.on('display.uk.check', function(){
            if ($this.element.is(":visible"))  $this.check();
        });
    },

    check: function() {

        var children = this.element.children('li:not(.uk-tab-responsive)').removeClass('uk-hidden');

        if (!children.length) return;

        var top          = (children.eq(0).offset().top + Math.ceil(children.eq(0).height()/2)),
            doresponsive = false,
            item, link;

        this.responsivetab.lst.empty();

        children.each(function(){

            if (UI.$(this).offset().top > top) {
                doresponsive = true;
            }
        });

        if (doresponsive) {

            for (var i = 0; i < children.length; i++) {

                item = UI.$(children.eq(i));
                link = item.find('a');

                if (item.css('float') != 'none' && !item.attr('uk-dropdown')) {

                    item.addClass('uk-hidden');

                    if (!item.hasClass('uk-disabled')) {
                        this.responsivetab.lst.append('<li><a href="'+link.attr('href')+'" data-index="'+i+'">'+link.html()+'</a></li>');
                    }
                }
            }
        }

        this.responsivetab[this.responsivetab.lst.children('li').length ? 'removeClass':'addClass']('uk-hidden');
    }
});
})(UIkit);

为连接的切换器组件创建了类似的代码。

你可以在这里看到我的问题的演示:http://notesx.net/customrenderer.nsf/demo.xsp

源代码在这里:https://github.com/zeromancer1972/CustomRendererDemo/blob/master/ODP/XPages/demo.xsp

因为这是库本身的一部分,所以我想找到一种从库外部调用它的方法。

非常感谢任何想法!

较新版本的 uikit 有一个 init 方法,升级并从组合框的 onComplete 事件中调用它。

<xp:comboBox
    id="comboBox1">
    <xp:selectItems>
        <xp:this.value><![CDATA[#{javascript:return ["value 1", "value 2"];}]]></xp:this.value>
    </xp:selectItems>
    <xp:eventHandler
        event="onchange"
        submit="true"
        refreshMode="partial"
        refreshId="page"
        onComplete="$.UIkit.init();">
    </xp:eventHandler>
</xp:comboBox>