jQuery的ContextMenu插件评比+改造
2009 5 24 11:03 AM 3344次查看
分类:JavaScript 标签:JavaScript, jQuery
不过搜了下,发现了3个右键菜单插件,所以就直接借用了。
看他的评论,第1个插件是最老的,所以先无视了;第2个非常轻巧,但感觉定制起来很麻烦,因为提供的接口太少了;于是看了看第3个,觉得做得不错,于是看了看文档,似乎说得比第一个要好。
于是试用了下第3个,结果发现2点无语的:
- 不兼容live函数,我用live绑定的click事件都无法触发了。
- 不能自己处理事件。我需要在触发右键菜单时,根据触发目标来设置菜单项是否可用。虽然插件提供了disable功能,却不将事件放出,于是没机会设置disable。
不得已转向了第1个,发现配置果然很开放,事件分为了onContextMenu和onShowMenu这2种,完全可以在这删除菜单项了~
然而仍有2点遗憾:
- 菜单项与事件的绑定是用id,那么2个菜单就不能有相同的菜单项了,导致命名很头疼。而第3个插件是在里面加了个a标签,通过href属性来定位事件,所以不存在冲突。
- 使用jQuery UI的draggable时,拖动对象不会导致菜单消失,假如拖动后再点按钮,可能导致出错(我是这么猜测的,因为DOM对象已经不在原位置了)。
第1个很简单,找到display函数,将$('#'+id, menu)改为$('.'+id, menu)即可。
第2个非常复杂,首先可以这样做:
$('body').mousedown(function () {$('#jqContextMenu').hide();});
测试一下,发现菜单会消失了,但是阴影仍存在。于是在构造菜单时,可以传flase给shadow,这样就不会显示阴影了。另一个办法就是找到shadow = $('<div></div>'),改为shadow = $('<div id="jqContextMenuShadow"></div>');然后将这个div也hide即可。
不过测试时仍发现个问题,由于mousedown比click先触发,于是点击菜单项时,还没触发click事件,菜单已经被hide了,绑定事件就没法触发了…
解决办法有3种:
- 第1种是找到$('.'+id, menu).bind('click', function(e)(注意之前我已经将#改为.了),改为$('.'+id, menu).bind('mousedown', function(e),这样由于jQuery的事件是冒泡处理的,body是在菜单项之后才捕捉到事件,所以符合要求。不过该方法破坏了点击事件,因为mousedown后不一定会click。
- 第2种则是让菜单项的mousedown不进行冒泡,这样body就不会捕获到mousedown事件了,而click事件仍能正确处理。
实现也很简单,将上面的代码改为这个即可:$('.'+id, menu).bind('mousedown', function() {return false;}).bind('click', function(e)。
不过这种方法破坏了mousedown事件,如果需要捕获这个事件的话(99%的情况不会,因为这个本来就是隐藏的),则可以自行修改这段代码,或者触发一个自定义的事件。 - 第3种则最复杂,不过不需要修改源码。方法就是获取鼠标位置,判断是否在菜单上方,如果不是才hide菜单。
代码我就不写了,因为我不需要,第2种已经满足我的需求了。 - 第4种是个笨方法,把其他东西全放在一个div里(例如wrap),菜单则放在外面,然后只在wrap上绑定mousedown。
虽然方法很笨,但是最为简单,几乎不需要改代码~
由于该插件采用了MIT和GPL授权,修改源码是需要遵守该授权的。嘛,我就当这样说明也属于开放源码了~
0条评论 你不来一发么↓