2010-02-03 27 views
2

我有一對夫婦的菜單是這樣的:如何定位dijit.menu相對於其觸發器?

// Contextual Menu 
// triggers 
<div id="contextMenuTrigger0">0</div> 
<div id="contextMenuTrigger1">1</div> 
// menu 
<div dojoType="dijit.Menu" 
    targetNodeIds="contextMenuTrigger0, contextMenuTrigger1" 
    leftClicktoOpen="true" style="display:none"> 
     <div dojoType="dijit.MenuItem" class="first">Item One</div> 
     <div dojoType="dijit.MenuItem">Item Two</div> 
     <div dojoType="dijit.MenuItem">Item Three</div> 
     <div dojoType="dijit.MenuItem">Item Four is really, really long item.</div> 
</div> 

這:

// Tools Menu 
// trigger 
<div id="toolsButton">Tools</div> 
// menu 
<div dojoType="dijit.Menu" class="toolsMenu" 
    targetNodeIds="toolsButton" 
    leftClicktoOpen="true" style="display:none"> 
     <div dojoType="dijit.MenuItem" class="first">Item One</div> 
     <div dojoType="dijit.MenuItem">Item Two</div> 
     <div dojoType="dijit.MenuItem">Item Three</div> 
     <div dojoType="dijit.MenuItem">Item Four</div> 
</div> 

眼下,菜單打開時,它出現在鼠標下。我希望它出現在相對於觸發器*的特定位置。我找到了啓動和onOpen事件,並試圖編寫一個函數來設置菜單的domNode的風格,但它們似乎沒有生效。

另外,我沒有看到找出哪個節點是觸發器的情況下,有多個的方式。

我看到this & this,但沒有能夠進一步與他們進一步。

* FWIW,我希望它們的位置使菜單的左上角與上下文觸發器的右上角對齊,並與工具菜單的左下角對齊。

回答

3

事實證明,dojo.popup.open(我猜菜單從繼承)有一個參數(東方),你可以使用相對於一個節點的菜單定位。我最終定義了一個定製觸發器類,它知道如何利用它。 (我還創建了子類有不同的取向其他菜單類型,但我會離開那些出了清晰的緣故。)

UPDATE:根據this page,變量替換方法我用的不建議使用templateString。相反,你應該創建一個attributeMap,我在下面做了。

http://docs.dojocampus.org/quickstart/writingWidgets

// Define a basic MenuTrigger 
dojo.declare("my.MenuTrigger", [dijit._Widget, dijit._Templated], { 
    // summary: 
    //  A button that shows a popup. 
    //  Supply label and popup as parameter when instantiating this widget. 

    label: null, 
    orient: {'BL': 'TL', 'BR': 'TR'}, // see http://api.dojotoolkit.org/jsdoc/1.3.2/dijit.popup.__OpenArgs (orient) 
    templateString: "<a href='#' class='button enabled' dojoAttachEvent='onclick: openPopup' onClick='return false;' ><span dojoAttachPoint='labelNode'></span></a>", 
    disabled: false, 
    attributeMap: { 
     label: { 
      node: "labelNode", 
      type: "innerHTML" 
     } 
    }, 

    openPopup: function(){ 
     if (this.disabled) return; 
     var self = this; 

     dijit.popup.open({ 
      popup: this.popup, 
      parent: this, 
      around: this.domNode, 
      orient: this.orient, 
      onCancel: function(){ 
       console.log(self.id + ": cancel of child"); 
      }, 
      onExecute: function(){ 
       console.log(self.id + ": execute of child"); 
       dijit.popup.close(self.popup); 
       self.open = false; 
      } 
     }); 

     this.open = true; 
    }, 

    closePopup: function(){ 
     if(this.open){ 
      console.log(this.id + ": close popup due to blur"); 
      dijit.popup.close(this.popup); 
      this.open = false; 
     } 
    }, 

    toggleDisabled: function() { 
     this.disabled = !this.disabled 
     dojo.toggleClass(this.domNode, 'buttonDisabled'); 
     dojo.toggleClass(this.domNode, 'enabled'); 
     dojo.attr(this.domNode, 'disabled', this.disabled); 
    }, 

    _onBlur: function(){ 
     // summary: 
     //  This is called from focus manager and when we get the signal we 
     //  need to close the drop down 
     //  (note: I don't fully understand where this comes from 
     //  I couldn't find docs. Got the code from this example: 
     //  http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/_base/test_popup.html 
     this.closePopup(); 
    } 
}); 

// create some menus & triggers and put them on the page 
dojo.addOnLoad(function(){ 
    // MENU 
    cMenu = new dijit.Menu(); 
    cMenu.addChild(new dijit.MenuItem({ label: "First Item" })); 
    cMenu.addChild(new dijit.MenuItem({ label: "Second Item" })); 
    cMenu.addChild(new dijit.MenuItem({ label: "Third Item" })); 
    cMenu.addChild(new dijit.MenuItem({ label: "Fourth Item is truly a really, really, really long item" })); 

    // TRIGGER 
    cTrigger = new my.MenuTrigger({ 
     id: "cTrigger", 
     popup: cMenu 
    }).placeAt(dojo.body()); 
    cTrigger = new my.MenuTrigger({ 
     id: "cTrigger2", 
     popup: cMenu 
    }).placeAt(dojo.byId('contextTriggerContainer2')); 
}); 
0

正如我從dijit.Menu源代碼可以看出,您需要的功能並不支持開箱即用。
我能想到的是聲明一個繼承自dijit.Menu的新窗口小部件並覆蓋bindDomNode方法。它結合_openMyself處理程序onClick事件是這樣的:

dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself") 

_openMyself處理從出現在作爲參數的事件對象需要COORDS。
所以這個想法是通過一個製作的事件對象與期望的座標。

dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, function(){ 
    var e = { target: desiredTarget, pageX: desiredX, pageY: desiredY }; 
    this._openMyself(e); 
}); 
4

我發現下面的CSS覆蓋工作得很好,如果你只是想在自動定位的相對差異:

.dijitMenuPopup { 
    margin-left: -25px !important; 
    margin-top: 15px !important; 
} 
相關問題