我正在使用 ExtJS 4 框架,并在我的主应用程序面板中使用Raphael.js
。
首先,我试图阻止常规上下文菜单显示,我发现了非常简单的解决方案。
raphael_element.node.oncontextmenu = function()
{
return false;
}
这很好用,但在返回false之前我想添加一些代码来显示我自己的自定义菜单。
有谁知道怎么做?
我有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>
正如您所看到的,我有css class
(代码不在这里,它不相关)的样式,id=rect_menu
显示用户右键单击即。 Raphael矩形对象。
任何人都可以展示一种方式,也许是不涉及jquery的小型演示? Thnaks
答案 0 :(得分:3)
您可以使用Ext在floating组件中显示自定义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菜单从其隐藏机制中受益:< / p>
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();
}
});
这是使用最后一个例子的fiddle。它不使用Raphael,但从获得一个不重要的DOM元素的那一刻起。
编辑示例与实际的Raphael元素
我用实际的Raphael元素更新了my fiddle。它确实按预期工作。
很酷的是,元素的click事件完全尊重矢量路径边界,这意味着您可以精确地决定菜单的弹出位置。不那么酷的是,例如,着名的tiger,这将意味着240个事件处理程序...有点performance性能明智....你总是可以将处理程序添加到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
});
});
答案 1 :(得分:0)
这也很好,并且已获得MIT许可
https://swisnl.github.io/jQuery-contextMenu//
JsFiddle (example copied from link above)
$(function() {
$.contextMenu({
selector: '.context-menu-one',
callback: function(key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
"edit": {name: "Edit", icon: "edit"},
"cut": {name: "Cut", icon: "cut"},
copy: {name: "Copy", icon: "copy"},
"paste": {name: "Paste", icon: "paste"},
"delete": {name: "Delete", icon: "delete"},
"sep1": "---------",
"quit": {name: "Quit", icon: function(){
return 'context-menu-icon context-menu-icon-quit';
}}
}
});
$('.context-menu-one').on('click', function(e){
console.log('clicked', this);
})
});