extjs菜单隐藏问题

近期由于项目中大量使用iframe导致父级页面的菜单显示后,在子页面的操作不能自动隐藏菜单。为此,笔者查看了extjs的源码,发现,extjs的菜单基本都是通过Ext.menu.MenuMgr进行管理的,我们在创建菜单时会自动调用其register方法,将菜单注册到管理器中,而管理器的初始化方法,针对document添加了mousedown事件,判断只要不是针对菜单选项的点击事件那么都会调用hideAll(遍历容器中的菜单对象并调用hide方法)方法。

以下为源码注释:如果有不正确的地方希望能不令赐教。

Ext.menu.Menu = Ext.extend(Ext.Container, {
 . . .
 initComponent : function() {
  if (Ext.isArray(this.initialConfig)) {
   Ext.apply(this, {
      items : this.initialConfig
     })
  }
  this.addEvents("click", "mouseover", "mouseout", "itemclick");
  Ext.menu.MenuMgr.register(this); //注意这里将菜单本身放入到容器中。
  if (this.floating) {
   Ext.EventManager.onWindowResize(this.hide, this)
  } else {
   if (this.initialConfig.hidden !== false) {
    this.hidden = false
   }
   this.internalDefaults = {
    hideOnClick : false
   }
  }
  Ext.menu.Menu.superclass.initComponent.call(this);
  if (this.autoLayout) {
   var a = this.doLayout.createDelegate(this, []);
   this.on({
      add : a,
      remove : a
     })
  }
 },
. . .
------------管理器代码,调用hideall可以隐藏所有菜单。
Ext.menu.MenuMgr = function() {
 var g, d, c = {}, a = false, l = new Date();
 function n() {//初始化方法
  g = {};
  d = new Ext.util.MixedCollection();
  Ext.getDoc().addKeyListener(27, function() {
     if (d.length > 0) {
      i()
     }
    })
 }
 function i() {//隐藏方法
  if (d && d.length > 0) {
   var o = d.clone();
   o.each(function(p) {
      p.hide()
     });
   return true
  }
  return false
 }
 function e(o) {//隐藏事件处理
  d.remove(o);
  if (d.length < 1) {
   Ext.getDoc().un("mousedown", m);
   a = false
  }
 }
 function k(o) {//显示事件处理
  var p = d.last();
  l = new Date();
  d.add(o);
  if (!a) {
   Ext.getDoc().on("mousedown", m);
   a = true
  }
  if (o.parentMenu) {
   o.getEl().setZIndex(parseInt(o.parentMenu.getEl()
       .getStyle("z-index"), 10)
     + 3);
   o.parentMenu.activeChild = o
  } else {
   if (p && !p.isDestroyed && p.isVisible()) {
    o.getEl().setZIndex(parseInt(p.getEl().getStyle("z-index"), 10)
      + 3)
   }
  }
 }
 function b(o) {//隐藏之前事件处理
  if (o.activeChild) {
   o.activeChild.hide()
  }
  if (o.autoHideTimer) {
   clearTimeout(o.autoHideTimer);
   delete o.autoHideTimer
  }
 }
 function h(o) {//显示之前事件处理
  var p = o.parentMenu;
  if (!p && !o.allowOtherMenus) {
   i()
  } else {
   if (p && p.activeChild) {
    p.activeChild.hide()
   }
  }
 }
 function m(o) {//绑定document的鼠标事件
  if (l.getElapsed() > 50 && d.length > 0 && !o.getTarget(".x-menu")) {
   i()
  }
 }
 return {
  hideAll : function() {
   return i()
  },
  register : function(o) {
   if (!g) {
    n()
   }
   g[o.id] = o;
   o.on({
      beforehide : b,
      hide : e,
      beforeshow : h,
      show : k
     })
  },
  get : function(o) {
   if (typeof o == "string") {
    if (!g) {
     return null
    }
    return g[o]
   } else {
    if (o.events) {
     return o
    } else {
     if (typeof o.length == "number") {
      return new Ext.menu.Menu({
         items : o
        })
     } else {
      return Ext.create(o, "menu")
     }
    }
   }
  },
  unregister : function(o) {
   delete g[o.id];
   o.un("beforehide", b);
   o.un("hide", e);
   o.un("beforeshow", h);
   o.un("show", k)
  },
  registerCheckable : function(o) {
   var p = o.group;
   if (p) {
    if (!c[p]) {
     c[p] = []
    }
    c[p].push(o)
   }
  },
  unregisterCheckable : function(o) {
   var p = o.group;
   if (p) {
    c[p].remove(o)
   }
  },
  onCheckChange : function(q, s) {
   if (q.group && s) {
    var u = c[q.group], p = 0, o = u.length, t;
    for (; p < o; p++) {
     t = u[p];
     if (t != q) {
      t.setChecked(false)
     }
    }
   }
  },
  getCheckedItem : function(q) {
   var s = c[q];
   if (s) {
    for (var p = 0, o = s.length; p < o; p++) {
     if (s[p].checked) {
      return s[p]
     }
    }
   }
   return null
  },
  setCheckedItem : function(q, t) {
   var s = c[q];
   if (s) {
    for (var p = 0, o = s.length; p < o; p++) {
     if (s[p].id == t) {
      s[p].setChecked(true)
     }
    }
   }
   return null
  }
 }
}();

//这里需要注意的是我们在调用hideAll方法前,需要想源码中一样确认下,事件的触发对象不是menu中的元素,否则的话,容易使一些带有菜单的组件如(时间控件)的功能失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值