您可以使用 Ext 在浮动组件中显示您的自定义 HTML:
var menu = Ext.create('Ext.Component', {
floating: true
,html: ['<ul id="rect_menu" class="contextMenu">',
'<li><a href="call_to_js_function">Set aaa</a></li>',
'<li><a href="call_to_js_function">Set xxx</a></li>',
'<li><a href="call_to_js_function">Set ccc</a></li>',
'</ul>'].join('')
});
Ext.get(raphael_element.node).on({
contextmenu: function(e) {
menu.showAt(e.getXY());
e.preventDefault();
}
});
但是,显示菜单并不是棘手的部分。隐藏菜单的逻辑,无论是当用户点击它之外,还是按下 ESC 键时,都涉及更多。这就是为什么我会使用常规Menu
让 Ext 为我们完成繁重的工作。
var menu = Ext.create('Ext.menu.Menu', {
items: [{
text: 'Set aaa'
,handler: function() {
// logic for aaa
}
}, {
text: 'Set bbb'
,handler: function() {
// logic for bbb
}
}]
});
Ext.get(raphael_element.node).on({
contextmenu: function(e) {
menu.showAt(e.getXY());
e.preventDefault();
}
});
现在,如果您对使用所有菜单系统、Ext 菜单项等不感兴趣,并且您真的想呈现自己的 HTML,您仍然可以利用 Ext 菜单从其隐藏机制中受益:
var menu = Ext.create('Ext.menu.Menu', {
// This will prevent the icon gutter from showing, and your component from
// being left padded
plain: true
,items: [{
xtype: 'component'
,html: ['<ul id="rect_menu" class="contextMenu">',
'<li><a href="call_to_js_function">Set aaa</a></li>',
'<li><a href="call_to_js_function">Set xxx</a></li>',
'<li><a href="call_to_js_function">Set ccc</a></li>',
'</ul>'].join('')
}]
});
Ext.get(raphael_element.node).on({
contextmenu: function(e) {
menu.showAt(e.getXY());
e.preventDefault();
}
});
这是使用最后一个示例的小提琴。它不使用 Raphael,但从你得到一个不具有任何重要性的 DOM 元素的那一刻起。
使用实际 Raphael 元素编辑示例
我用实际的拉斐尔元素更新了我的小提琴。它确实按预期工作。
很酷的是元素的点击事件完全尊重矢量路径边界,这意味着您可以精确地决定菜单将在哪里弹出或不弹出。不那么酷的是,例如,著名的tiger,这将意味着 240 个事件处理程序......在性能方面有点糟糕......你总是可以将处理程序添加到 SVG 元素而不是单个形状元素,但是当然,菜单将绑定到整个绘图矩形而不是单个部分。
// --- Creating a ball (see http://raphaeljs.com/ball.html)
Raphael.fn.ball = function (x, y, r, hue) {
hue = hue || 0;
return this.set(
this.ellipse(x, y + r - r / 5, r, r / 2).attr({fill: "rhsb(" + hue + ", 1, .25)-hsb(" + hue + ", 1, .25)", stroke: "none", opacity: 0}),
this.ellipse(x, y, r, r).attr({fill: "r(.5,.9)hsb(" + hue + ", 1, .75)-hsb(" + hue + ", .5, .25)", stroke: "none"}),
this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
);
};
var R = Raphael("holder"), x = 310, y = 180, r = 150;
var ball = R.ball(x, y, r, Math.random());
// --- Creatin a custom menu
var menu = Ext.create('Ext.menu.Menu', {
plain: true
,cls: 'myContextMenu'
,items: [{
xtype: 'component'
,html: ['<ul id="rect_menu" class="contextMenu">',
'<li><a href="call_to_js_function">Set aaa</a></li>',
'<li><a href="call_to_js_function">Set xxx</a></li>',
'<li><a href="call_to_js_function">Set ccc</a></li>',
'</ul>'].join('')
}]
});
// --- Adding menu handler to all ball's elements
var contextMenuHandler = function(e) {
menu.showAt(e.getXY());
e.preventDefault();
};
Ext.each(ball, function(raphaelElement) {
Ext.fly(raphaelElement.node).on({
contextmenu: contextMenuHandler
});
});