科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件MzPopupLayer 可盖住flash的层基类

MzPopupLayer 可盖住flash的层基类

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

一个可以盖住select、iframe、flash的层基类控件

作者:meizz 来源:CSDN 2008年1月20日

关键字: 层基类 FLASH 盖住 MzPopupLayer

  • 评论
  • 分享微博
  • 分享邮件

Subject: popup layer, cross browser(IE5.0+ Firefox Netscape Mozilla Opera)
NameSpace:  System.Web.UI.WebControls.MzPopupLayer


    网页里做脚本控件的时候经常需要一个层的依托,比如自定义的右键菜单层,下拉式菜单层,模拟窗口层,日期选择录入控件层等等,这些层一般的人都是以一个绝对定位的DIV做的,在老版的http://www.microsoft.com/china 下拉菜单就是用这种DIV层,但是这种层有一个很致命的地方,会被页面里的<select>或者<iframe>或者FLASH之类的东东遮挡住(即使将z-index设置得再高也是无用的),因此需要使用别的技术来实现,所以我想到了用<iframe>作层的载体,它可以“盖”住select,iframe,flash。但是用它当然没有象DIV那么简单,所以我特别封装了这么一个基类,供其它的脚本控件调用。

    在IE5.5+里有一个特殊的对象 window.createPopup() 这个怪胎东东可以跨框架显示,可以“伸”到网页之外显示,拿来做下拉菜单、右键菜单层简直是太好不过了,所以我把它也封装到我这个类里去了,做出一个统一的接口供调用者调用。

 

 


 


/*---------------------------------------------------------------------------*\
|  Subject:    popup layer  cross browser(IE5.0+ Firefox NS Moz Opera)
|  NameSpace:  System.Web.UI.WebControls.MzPopupLayer
|  Author:     meizz
|  Created:    2006-03-19
|  Version:    2006-04-20
|-------------------------------------------------------------
|  MSN: huangfr@msn.com   QQ: 112889082   http://www.meizz.com
|  Email: mz@126.com      CSDN ID:meizz   Copyright (c)  meizz
\*---------------------------------------------------------------------------*/

 

function MzPopupLayer(iframe)
{
  this.id= this.getHashCode();
  this.name=this.id +"_popup";
  this.usePopup = false;
  if (typeof iframe=="undefined")
  {
    try
    {
      this.element =window.createPopup();
      this.usePopup=true;
      this.document=this.element.document;
    }
    catch (ex){this.usePopup = false;}
  }
  this.isOpen=false;
  this.binder=null;
  this.lock=false;
  this.autoFit=false;
  if(!this.usePopup)
  {
    if(document.all)
    {
      if(document.readyState=="complete") document.body.innerHTML+=
        "<iframe id='"+ this.id +"' name='"+ this.name +"'></iframe>";
      else document.write("<iframe id='"+this.id+"' name='"+this.name+"'></iframe>");
      this.element=document.getElementById(this.id);
    }
    else
    {
      this.element = document.createElement("IFRAME");
      this.element.id = this.id;
      this.element.name=this.name;
      document.body.appendChild(this.element);
    }
    with(this.element.style)
    {
      width=0; height=0; borderWidth=0;
      zIndex=MzPopupLayer.zIndex++; position="absolute";
    }
    this.style = this.element.style;var me=this;
    document.attachEvent("onclick", function(e)
    {
      e=e||window.event; e=e.target||e.srcElement;
      if( me.lock) me.srcElement=e;
      if(!me.lock && me.isOpen && e!=me.srcElement) me.hide();
    });
    document.attachEvent("oncontextmenu", function(e)
    {
      if(me.isOpen) me.hide();
    });
    document.attachEvent("onkeydown", function(e)
    {
      e=e||window.event; var k=e.which||e.keyCode;
      if(!me.lock && me.isOpen && (k==27 || k==9)) me.hide();
    });
    window.attachEvent("onscroll", function(){if(me.isOpen)me.hide();});

 

    function sleep(n){var start=new Date().getTime(); //for opera only
    while(true) if(new Date().getTime()-start>n) break;}
    if(window.opera){sleep(500);this.document=this.element.document;}
    else  this.document=frames[this.name].document;

 

    var html = "<html><head></head><body style='border-width:0;padding:0;"+
      "margin:0;overflow:hidden;background-color:white'></body></html>";
    this.document.write(html); this.document.close();

 

    if(window.opera) this.document=this.element.document;
    else this.document=frames[this.name].document;
  }
}
MzPopupLayer.Extends(System, "MzPopupLayer");
MzPopupLayer.zIndex=520;

 

MzPopupLayer.prototype.show = function(left, top, width, height, trigger)
{
  if(this.usePopup)
  {
    this.element.show(left, top, width, height, trigger);
    this.isOpen=this.element.isOpen;
  }
  else
  {
    this.lock=true;
    this.isOpen=true;
    this.binder=trigger;
    this.element.style.top = top;
    this.element.style.left = left;
    this.element.style.width = width;
    this.element.style.height = height;
    setTimeout("Instance('"+this.id+"').lock=false",1);
  }
};

 

MzPopupLayer.prototype.bind = function(trigger, width, height)
{
  var e=trigger, x=e.offsetLeft, y=e.offsetTop;
  while(e=e.offsetParent){x+=e.offsetLeft; y+=e.offsetTop;}

 

  var DL, DT, top=0, left=0;

 

  if(window.pageXOffset){DL=window.pageXOffset;}
  else if(document.documentElement&&document.documentElement.scrollLeft){
    DL=document.documentElement.scrollLeft;}
  else if(document.body){DL=document.body.scrollLeft;}

 

  if(window.pageYOffset){DT=window.pageYOffset;}
  else if(document.documentElement&&document.documentElement.scrollTop){
    DT=document.documentElement.scrollTop;}
  else if(document.body){DT=document.body.scrollTop;}

 

  if(this.usePopup)
  {
    if(this.autoFit)
    {
      this.element.show(0, 0, 1, 1, trigger);
      width = this.document.body.scrollWidth;
      height = this.document.body.scrollHeight;
    }
    top=trigger.offsetHeight;
    if(screen.availHeight-(screenTop+y+top-DT)<height) top=0-height;
  }
  else
  {
    var DW, DH;
    if(window.innerWidth){DW=window.innerWidth;}
    else if(document.documentElement&&document.documentElement.clientWidth){
      DW=document.documentElement.clientWidth;}
    else if(document.body){DW=document.body.clientWidth;}

 

    if(window.innerHeight){DH=window.innerHeight;}
    else if(document.documentElement&&document.documentElement.clientHeight){
      DH=document.documentElement.clientHeight;}
    else if(document.body){DH=document.body.clientHeight;}

 

    try{this.element.style.width="1px"; //possible error on reload page Netscape
    this.element.style.height="1px";
    this.document.body.style.overflow="auto";
    if(!window.opera) var EW=this.document.body.scrollWidth;  //always retrieve inexact width in Opera
    var EH=this.document.body.scrollHeight;
    this.document.body.style.overflow="hidden";}
    catch(ex){EW=width||100; EH=height||100;} width=EW; height=EH;

 

    var OH=trigger.offsetHeight;
    if(window.opera && trigger.tagName=="INPUT"){x+=3; y+=3; OH-=6;} //repair for Opera
    if(DT+DH-y-OH<height&&y-DT>height) top=y-height; else top=y+OH;
    if (x + width > DL + DW) left = DW + DL - width;
    else if (x - DL < 0) left = DL; else left = x;
  }
  this.show(left, top, width, height, trigger);
};

 

MzPopupLayer.prototype.hide = function()
{
  if(this.usePopup)
  {
    this.element.hide();
    this.isOpen=this.element.isOpen;
  }
  else
  {
    this.isOpen=false;
    this.binder=null;
    this.srcElement=null;
    with(this.element.style){width="0px"; height="0px";}
  }
};

 

MzPopupLayer.prototype.createStyleSheet = function(url)
{
  if(this.document.createStyleSheet)
  {
    if(typeof url!="string") return this.document.createStyleSheet();
    else return this.document.createStyleSheet(url);
  }
  var e=null, d=this.document;if(url){ e=d.createElement("LINK");
  e.href=url;e.type="text/css"; e.rel="Stylesheet";}else{
  e=d.createElement("STYLE");   e.type="text/css"; }
  d.getElementsByTagName("HEAD")[0].appendChild(e);
  try{e = d.styleSheets[d.styleSheets.length-1];}catch (ex){
  throw "Your browser isn't support document.styleSheets!";}
  return new MzStyleSheet(e);
}
function MzStyleSheet(styleSheet)
{
  this.self=styleSheet;
  if (this.self.rules) this.rules=this.self.rules;
  else if (this.self.cssRules) this.rules=this.self.cssRules;
  this.addRule = function(selector,style,i)
  {
    if (this.self.addRule) return this.self.addRule(selector,style,i);
    else if (this.self.insertRule)
    {
      if(typeof i=="undefined")i=this.self.cssRules.length;
      return this.self.insertRule(selector+"{"+style+"}",i);
    }
  };
  this.removeRule = function(i)
  {
    if (this.self.removeRule) this.self.removeRule(i);
    else if (this.self.deleteRule)
    {
      if(typeof i=="undefined")i=0;this.self.deleteRule(i);
    }
  };
}


 

 

 


成员属性列表:
.document  层体的document对象,可以做如 document.body 之类的操作
.isOpen  布尔值 指层的显示/隐藏状态
.autoFit  布尔值 层的高宽将自适应其加载的内容高宽
.usePopup  布尔值 指层目前是使用window.createPopup()还是使用iframe

成员方法列表:
.show(left, top, width, height, trigger)
.bind(trigger, width, height)
.hide()
.createStyleSheet([url])  //此方法在Opera里有BUG


查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章