在之前的一篇文章中我提到过menu的disableItem方法并无法阻止对绑定事件的调用,当时的解决方案基于良好的事件绑定方式,也就是事件全部用jQuery绑定。现实总是残酷的,大部分的代码仍然习惯使用onclick方式绑定事件,这样兼容javascript原生的onclick绑定事件的方式就显得很有必要。
前一篇文章中使用的方式是修改源码,这里为了最大限度保持源码的纯洁度,采用直接覆写menu的disableItem和enableItem方法了,在引入easyui核心库后,做以下覆盖定义即可:
实现代码:
- /**
- * menu方法扩展
- * @param {Object} jq
- * @param {Object} region
- */
- $.extend($.fn.menu.methods, {
- /**
- * 激活选项(覆盖重写)
- * @param {Object} jq
- * @param {Object} itemEl
- */
- enableItem: function(jq, itemEl){
- return jq.each(function(){
- var t = $(itemEl);
- var state = t.data('menu.item');
- if (!state) {
- t.data('menu.item', {
- options: {}
- });
- }
- state = t.data('menu.item');
- if(state.onclickStr){
- var newclick = new Function(state.onclickStr);
- t.bind('click',newclick);
- }else{
- if (state.onclick) {
- t.bind('click', state.onclick);
- state.onclick = null;
- }
- }
- t.removeClass('menu-item-disabled');
- });
- },
- /**
- * 禁用选项(覆盖重写)
- * @param {Object} jq
- * @param {Object} itemEl
- */
- disableItem: function(jq, itemEl){
- return jq.each(function(){
- var t = $(itemEl);
- var state = t.data('menu.item');
- if (!state) {
- t.data('menu.item', {
- options: {}
- });
- }
- state = t.data('menu.item');
- var onclickStr = t.attr("onclick");
- if(onclickStr && onclickStr != ""){
- state.onclickStr = onclickStr;
- t.attr("onclick","");
- }else{
- 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"]);
- }
- }
- }
- }
- t.addClass('menu-item-disabled');
- });
- }}
- );
效果演示:
http://www.easyui.info/easyui/demo/menu/060.html
更新日志:
2012-12-19:
因为jQuery1.8.0版本开始调整$.data函数功能,故代码要稍作变成改动后的代码如下:
- /**
- * menu方法扩展
- * @param {Object} jq
- * @param {Object} itemEl
- */
- $.extend($.fn.menu.methods, {
- /**
- * 激活选项(覆盖重写)
- * @param {Object} jq
- * @param {Object} itemEl
- */
- enableItem : function(jq, itemEl) {
- return jq.each(function(){
- var jqElements = $(itemEl);
- var state = $.data(this, 'menu');
- if (jqElements.length > 0) {
- jqElements.each(function(){
- if ($(this).hasClass('menu-item-disabled')) {
- for(var i=0; i<state._eventsStore.length; i++){
- var itemData = state._eventsStore[i];
- if(itemData.target == this){
- //恢复超链接
- if (itemData.href) {
- $(this).attr("href", itemData.href);
- }
- //回复点击事件
- if (itemData.onclicks) {
- for (var j = 0; j < itemData.onclicks.length; j++) {
- $(this).bind('click', itemData.onclicks[j]);
- }
- }
- //设置target为null,清空存储的事件处理程序
- itemData.target = null;
- itemData.onclicks = [];
- $(this).removeClass('menu-item-disabled');
- }
- }
- }
- });
- }
- });
- },
- /**
- * 禁用选项(覆盖重写)
- * @param {Object} jq
- * @param {Object} itemEl
- */
- disableItem : function(jq, itemEl) {
- return jq.each(function() {
- var jqElements = $(itemEl);
- var state = $.data(this,'menu');
- if (jqElements.length > 0) {
- if (!state._eventsStore)
- state._eventsStore = [];
- jqElements.each(function(){
- if (!$(this).hasClass('menu-item-disabled')) {
- var backStore = {};
- backStore.target = this;
- backStore.onclicks = [];
- //处理超链接
- var strHref = $(this).attr("href");
- if (strHref) {
- backStore.href = strHref;
- $(this).attr("href", "javascript:void(0)");
- }
- //处理直接耦合绑定到onclick属性上的事件
- var onclickStr = $(this).attr("onclick");
- if (onclickStr && onclickStr != "") {
- backStore.onclicks[backStore.onclicks.length] = new Function(onclickStr);
- $(this).attr("onclick", "");
- }
- //处理使用jquery绑定的事件
- var eventDatas = $(this).data("events") || $._data(this, 'events');
- if (eventDatas["click"]) {
- var eventData = eventDatas["click"];
- for (var i = 0; i < eventData.length; i++) {
- if (eventData[i].namespace != "menu") {
- backStore.onclicks[backStore.onclicks.length] = eventData[i]["handler"];
- $(this).unbind('click', eventData[i]["handler"]);
- i--;
- }
- }
- }
- //遍历_eventsStore数组,如果有target为null的元素,则利用起来
- var isStored = false;
- for(var j=0; j<state._eventsStore.length; j++){
- var itemData = state._eventsStore[j];
- if(itemData.target==null){
- isStored = true;
- state._eventsStore[j] = backStore;
- }
- }
- //没有现成的,则push进去
- if(isStored==false){
- state._eventsStore[state._eventsStore.length] = backStore;
- }
- $(this).addClass('menu-item-disabled');
- }
- });
- }
- });
- }
- });