Bug描述:
在jQuery easyui 1.2.5版本中menu组件提供了disableItem和enableItem方法,用于设置菜单按钮中某个item是否可用,入参是某个item的selector。遗憾的是这两个方法基本都用不起来,分析了一下代码,这两个接口的实现写的真是太粗糙太糟糕了:
- /**
- *
- * @param {Object} _2d6 jQuery对象
- * @param {Object} _2d7 字符串 item的选择器描述
- * @param {Object} _2d8 布尔型 用于设置是设为可用还是设为不可用
- */
- function _2d5(_2d6, _2d7, _2d8){
- var t = $(_2d7);
- if (_2d8) {
- t.addClass("menu-item-disabled");
- //常态下_2d7咋的可能有onclick属性
- if (_2d7.onclick) {
- _2d7.onclick1 = _2d7.onclick;
- _2d7.onclick = null;
- }
- }
- else {
- t.removeClass("menu-item-disabled");
- //企图用_2d7的onclick1属性备份item的事件函数?显然不能达到目的。
- if (_2d7.onclick1) {
- _2d7.onclick = _2d7.onclick1;
- _2d7.onclick1 = null;
- }
- }
- };
解决方案:
很多人可能会想,jQuery里面不就可以通过attr函数设置元素的disabled属性吗?可惜在w3c的标准中,只有button,select等Form元素才有这个属性,其它元素其实是没有的,即使你设置了其它元素的disabled属性为true,你也无法阻止点击他们时他们的响应事件。而easyui的menu显然不是通过button实现的,所以这招不是很有效果。
对于Dom元素上的事情绑定,又分为两种情况:
- javascript自身的onclick属性绑定js语句或者函数
- 使用jQuery里面的事件绑定机制将event绑定到Dom上
如果easyui menu 的disableItem和enableItem接口同时要处理这两种情况,那就较为复杂了,对于第一种情况,有同学可能想到利用jQuery的attr函数动态设置Dom元素的onclick属性值,但是不争气的是IE的处理机制跟别的浏览器不太一样,即便是设置了Dom元素的onclick属性值,也得不到相应调用。
个人觉得,既然使用了jQuery框架就应该让代码更符合jQuery的规范,在事件处理机制上,jQuery应该是优于原生机制的,onclick方式绑定事件耦合度较高,不够灵活,在使用了jQuery的前提下就不提倡使用了,如果抛开onclick方式绑定事件,实现disableItem和enableItem就较为简单了:
- 将原先绑定的用户事件备份到Dom元素中,用于enableItem的时候恢复。
- disable的时候解除命名空间不为 'menu'的click事件的绑定,不能全部解除
- enableItem的时候重新将备份的事件绑定到Dom上就可以了。
代码简述:
- function setDisabled(target, itemEl, disabled){
- var t = $(itemEl);
- var state = t.data('menu.item');
- if (!state) {
- t.data('menu.item', {
- options: {}
- });
- }
- state = t.data('menu.item');
- if (disabled) {
- t.addClass('menu-item-disabled');
- if (t.data("events")["click"]) {
- var eventData = t.data("events")["click"];
- for (var i = 0; i < eventData.length; i++) {
- if (eventData[i].namespace != "menu") {
- state.onclick = eventData[i]["handler"];
- t.unbind('click', eventData[i]["handler"]);
- }
- }
- }
- }
- else {
- t.removeClass('menu-item-disabled');
- if (state.onclick) {
- t.bind('click', state.onclick);
- state.onclick = null;
- }
- }
- };
效果演示:
http://www.easyui.info/easyui/demo/menu/menu_bug_1.html
更新日志:
2012-06-05更新:
增加对原生javascript使用onclick方式绑定事件的支持,详细内容参见《menu组件disableItem方法无效之完善篇》