【问题标题】:How to change dojo content tab focus when closing a tab to focus on previous tab instead of first tab?关闭选项卡以关注上一个选项卡而不是第一个选项卡时如何更改 dojo 内容选项卡焦点?
【发布时间】:2012-04-09 15:03:31
【问题描述】:

我正在使用DojoDijit Layout 生成类似于Dijit Theme Tester Demo 的内容选项卡窗格。此处的所有选项卡都是可关闭的。

问题是:当我关闭一个选项卡时,它会返回到列表中的第一个选项卡,而不是上一个选项卡(在它旁边可用)。

您可以将其想象为在 Firefox 或 Chrome 中打开一个新选项卡并尝试关闭最后一个选项卡......在关闭选项卡时,它会将焦点更改为上一个选项卡,这是使用选项卡的可预测行为。但是对于dijit.TabContainers,默认情况下它会返回到第一个选项卡而不是前一个选项卡。当您考虑 UI 基础知识时,这是一个严重的缺陷。

我检查了dojo 文档,但没有找到任何提示。知道怎么做吗?

【问题讨论】:

    标签: javascript user-interface dojo dijit.layout


    【解决方案1】:

    好的,当单击 dijit.layout.ContentPane(选项卡)上的 [X] 按钮时,会生成一个事件 onClosedijit.layout .TabContainer 正在监听这个事件,所以当这个事件发生时,它会执行回调 closeChild() 然后函数 removeChild() 被执行,最后一个是你应该覆盖的。

    tabContainer 从 dijit.layout.StackContainer 继承了这两个函数,您应该查看 API 文档。

    因此,为了能够修改关闭选项卡的默认行为,您应该覆盖默认功能,在下面的示例中,我这样做了。阅读 cmets 以获取有关在何处添加逻辑的信息。

    例如

    <script>
        require([
            "dojo/parser",
    
            "dojo/_base/lang", //this is the one that has the extend function
            "dojo/topic", //this is needed inside the overrided function
    
            "dijit/layout/TabContainer",
            "dijit/layout/ContentPane", 
    
            "dojo/domReady!"
        ], function(Parser, lang, topic, tabContainer, contentPane){
            Parser.parse();
    
            // this will extend the tabContainer class and we will override the method in question
            lang.extend(tabContainer, {
    
                // this function, i copied it from the dijit.layout.StackContainer class
                removeChild: function(/*dijit._Widget*/ page){
    
                    // for this to work i had to add as first argument the string "startup"
                    this.inherited("startup", arguments);
    
                    if(this._started){
                        // also had to call the dojo.topic class in the require statement
                        topic.publish(this.id + "-removeChild", page);  
                    }
    
                    if(this._descendantsBeingDestroyed){ return; }
    
                    if(this.selectedChildWidget === page){
                        this.selectedChildWidget = undefined;
                        if(this._started){
                            var children = this.getChildren();
                            if(children.length){
    
                                // this is what you want to add your logic
                                // the var children (array) contains a list of all the tabs
                                // the index selects the tab starting from left to right 
                                // left most being the 0 index   
    
                                this.selectChild(children[0]);
                            }
                        }
                    }
    
                    if(this._started){
                        this.layout();
                    }
                }
            });
    
            // now you can use your modified tabContainer WALAAAAAAA!
            // from here on, normal programmatic tab creation
            var tc = new tabContainer({
                style: "height: 100%; width: 100%;",
            }, "tab-container-div-id");
    
            var cp1 = new contentPane({
                title: "First Tab",
                closable: true
            });
            tc.addChild(cp1);
    
            var cp2 = new contentPane({
                title: "Second Tab",
                closable: true
            });
            tc.addChild(cp2);
    
            var cp3 = new contentPane({
                title: "Third Tab",
                selected: true,
                closable: true
            });
            tc.addChild(cp3);
    
            tc.startup();
        });
    </script>
    

    【讨论】:

      【解决方案2】:

      在 Dojo 1.10 中,恢复到前一个选项卡是 TabContainers 的正常行为(而不是恢复到第一个选项卡)。

      据推测,您可以使用dojo/aspect 来获取旧行为(警告:未测试):

      require( [ 'dijit/registry', 'dojo/aspect', 'dojo/_base/lang' ],
          function( registry, aspect, lang )
          {
              var tabContainer = registry.byId( 'tab_container');
              aspect.before( tabContainer, 'removeChild', lang.hitch( tabContainer, function( page )
              {
                  if(this.selectedChildWidget === page)
                  {
                      this.selectedChildWidget = undefined;
                      if(this._started)
                      {
                          var children = this.getChildren();
                          this.selectChild( children[0] );
                      }
                  }
      
                  return page;
              } ) );
          }
      );
      

      或者,您也可以在标签的ContentPane 上使用onClose 扩展点:

      require( [ 'dijit/registry', 'dojo/_base/lang' ],
          function( registry, lang ) {
              newTabPane.onClose = lang.hitch(this, function () {
                  // select first
                  var tabContainer = registry.byId('tab_container'),
                      all_tabs = tabContainer.getChildren();
                  tabContainer.selectChild( all_tabs[0] );
      
                  // allow save to go ahead
                  return true;
              });
          }
      );
      

      显然,这两种方法都允许您在关闭的选项卡上选择特定的不同窗格,而不是稍作调整...

      【讨论】:

        猜你喜欢
        • 2019-02-28
        • 1970-01-01
        • 2019-02-28
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多