我开发了一个简单的jQuery插件,当我右键单击div时工作正常,但当我点击第二个div时,上下文菜单出现在第一个div上。 Here's the jsfiddle。这个插件出了什么问题?
插件代码:
(function ( $ ) {
var menu = null;
$.fn.ctxMenu = function( options ) {
var settings = $.extend({
menuItems: null,
onclick: null
}, options );
show(this,settings.menuItems,settings.onclick);
};
function show(obj,menuItems,onclick){
obj.bind( "contextmenu", function(e) {
if (e.preventDefault) e.preventDefault();
if (e.stopPropagation) e.stopPropagation();
render(obj,e.offsetX, e.offsetY,menuItems,onclick);
});
obj.bind( "click", function(e) {
if (menu != null)
menu.remove();
});
}
function render(obj,x,y,menuItems,onclick) {
if (menu != null)
menu.remove();
menu = $('<div id="menu" class="ctxMenu" />');
obj.append(menu);
menu.css('padding-top', '4px' );
menu.css('padding-bottom', '0px' );
menu.css('padding-left', '6px' );
menu.css('padding-right', '20px' );
menu.css('position', 'absolute' );
menu.css('top', y+'px' );
menu.css('left', x+'px' );
for (var i=0;i<menuItems.length;i++) {
var item = $('<div id="item" style="height:20px;padding:2px;cursor:default;" />');
item.attr('opt',menuItems[i].opt);
var p = $('<p id="p' + i + '" style="margin:0" />' );
p.text(menuItems[i].optCaption);
p.attr('opt',menuItems[i].opt);
item.append(p);
menu.append(item);
item.bind( "click", function(e) {
if (typeof onclick == 'function')
onclick.call(this,obj.attr('id'),$(e.target).attr('opt'));
});
}
}
}( jQuery ));
以及如何调用它的示例代码:
$div.ctxMenu({
menuItems: [ { opt:1, optCaption: "Option 1" },
{ opt:2, optCaption: "Option 2" },
{ opt:3, optCaption: "Option 3" }
],
change: function(id,opt) {
alert(id+"-"+opt);
}
});
答案 0 :(得分:1)
这是问题,父div没有相对定位。父母需要具有相对定位,而菜单div具有绝对定位,以便得到你想要的东西。
解决方案1(从代码开头开始):
$(document).ready(function () {
$container = $('#container');
var $div = $('<div style="width:300px;height:300px;border:1px solid black;float:left; position:relative"/>');
$div.appendTo($container);
addCtxMenu($div);
var $div2 = $('<div style="width:300px;height:300px;border:1px solid black;float:left; position:relative"/>');
$div2.appendTo($container);
addCtxMenu($div2);
});
//... Rest of code
解决方案2(从代码的第59行开始)
我将菜单div的位置更改为position:relative
,但这不太优雅,因为菜单占用了其父级的宽度。如果你不知道菜单的确切宽度,我会推荐解决方案1。
function render(obj,x,y,menuItems,onclick) {
if (menu != null)
menu.remove();
menu = $('<div id="menu" class="ctxMenu" />');
obj.append(menu);
menu.css('padding-top', '4px' );
menu.css('padding-bottom', '0px' );
menu.css('padding-left', '6px' );
menu.css('padding-right', '20px' );
menu.css('position', 'relative' );
menu.css('top', y+'px' );
menu.css('left', x+'px' );
for (var i=0;i<menuItems.length;i++) {
var item = $('<div id="item" style="height:20px;padding:2px;cursor:default;" />');
item.attr('opt',menuItems[i].opt);
var p = $('<p id="p' + i + '" style="margin:0" />' );
p.text(menuItems[i].optCaption);
p.attr('opt',menuItems[i].opt);
item.append(p);
menu.append(item);
item.bind( "click", function(e) {
if (typeof onclick == 'function')
onclick.call(this,obj.attr('id'),$(e.target).attr('opt'));
});
}
}
祝你的插件好运!