【问题标题】:jQuery plugin: context menu in second div not workingjQuery插件:第二个div中的上下文菜单不起作用
【发布时间】:2014-08-18 06:47:21
【问题描述】:

我开发了一个简单的 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);
            }
        });

【问题讨论】:

  • 因为父容器上没有position:relativejsfiddle.net/pevans02/dzSRR/7
  • 在 Firefox 中运行良好,您清除了网络缓存吗?
  • @PatrickEvans 我添加了 position:relative 仍然有问题
  • 那你没有把它放在正确的元素上,看我链接的小提琴,我把position:relative放在你动态创建的两个div上
  • @RafaelDiaz 我用 IE 和 Chrome 进行了测试,两者都有同样的问题。刚刚在FF中测试过,问题是(0,0)中出现了不同的上下文菜单。

标签: javascript jquery jquery-plugins


【解决方案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

FIDDLE

解决方案 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'));
            });
        }
    }

FIDDLE

祝你的插件好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-01
    • 2017-07-26
    • 2023-02-18
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多