WEB开发下面DIV层被OCX控件拦住问题的解决思想,以及结合EXTJS的解决方法

4 篇文章 0 订阅
4 篇文章 0 订阅
公司开发的WEB程序里面嵌入了一个大控件(ocx)。嵌入控件这种模式自然有它自身的好处,但是却有着一些致命的缺点......我个人认为能不用尽量不用,嵌入控件的WEB程序总觉得点不伦不类。
牢骚发完了,言归正传。



控件分为有窗口控件与无窗口控件,无窗口控件很好办

,如flash控件,可以通过添加wmode属性来解决挡住DIV层这个问题,添加的代码如下:
² 代码1-2 解决无窗口控件挡住DIV

<param name="wmode" value="opaque">









这种情况在使用DIV的网页里的测试如下







测试的代码是:

² 代码1-1 测试DIV与OCX控件

<div

style="position: absolute; left: 120; top: 450; width: 400px; height: 200px; background: red; z-index: 7">

<object classid="CLSID:4B5BEE59-EDD2-4082-A9F7-D65E1CA20FA7"width="100" height="100">

</object>

是第6层

</div>

<div

style="position: absolute; left: 40; top: 500; width: 400px; height: 100px; background: Blue; z-index: 9">

这是第7层

</div>

这是第7层

</div>

这种情况在EXTJS下边的测试情况如下图:






相关测试代码请参考代码1-1

注:如果我们的控件是一个无窗口控件如flash控件,可以通过添加wmode属性来解决挡住DIV层这个问题,添加的代码如下:

² 代码1-2 解决无窗口控件挡住DIV

<param name="wmode" value="opaque">



Ø 如何解决这些问题

值得庆幸的是Html的iframe、frame可以挡住OCX控件——实际上iframe以及frame本身是一个有窗口元素,有窗口元素之间是可以互相遮挡的,而我们的Div又可以与iframe窗口互相遮挡。 现在的问题变成了如何先用iframe挡住OCX窗口再用DIV挡住iframe。



² Code 2-1 用iframe遮挡OCX控件

<div

style="position: absolute; left: 120; top: 450; width: 400px; height: 200px; background: red; z-index: 7">

<object classid="CLSID:4B5BEE59-EDD2-4082-A9F7-D65E1CA20FA7"width="100" height="100">

</object>

是第6层

</div>

<div

style="position: absolute; left: 40; top: 500; width: 400px; height: 100px; background: Blue; z-index: 9">

<iframe id='iframei' src="javascript:false" style="position:absolute; visibility:inherit; top:0px; left:0px; height:'100%';width:'100%'; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';/">

</iframe>;

这是第7层

</div>



其中代码”

<iframe id='iframei' src="javascript:false" style="position:absolute; visibility:inherit; top:0px; left:0px; height:'100%';width:'100%'; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';/"></iframe>;”

就是创建一个与DIV等大的,透明的iframe框架。

实现的效果如下图:







现在我们已经解决了如何用DIV去遮挡OCX这个问题了。接下来我们要做的是如何去改造EXTJS类来让它们也可以挡住OCX控件。



EXTJS中对控件参用了继承的方法来实现扩展,所以我们只许要实现对恰当的父类进行改造就可以了,这里我们选择Panel类。接下我们将会在panel类里面添加一个等大的,透明的iframe窗口。以后在使用创建的panel控件,以及继承自panel的控件(如:window)都可以实现遮挡住OCX控件了。——继承的优势再一次得到的很好的体现。

由于要修改EXTJS的原码,所以我们使用它的Debug版本。

我们也许不想所有的panel以及其子孙下边都藏着一个iframe,所以这里我们添加一个属性来控制是否要添加一个iframe。实现如下



Ext.Panel = Ext.extend(Ext.Container, {



hasIframe: false,

……

下边我们就在实例化一个panel(或者其子孙)时添加一个iframe吧。

我选择了在panel渲染onRender时加入自己的代码:

onRender : function(ct, position) {

Ext.Panel.superclass.onRender.call(this, ct, position);

var el = this.el, d = el.dom;

// el 下边加入我们的iFrame

if (this.hasIframe)

{

var iframeid=this.id+"_iframe"

d.innerHTML+="<iframe id='"+iframeid+"' src=/"javascript:false/" style=/"position:absolute; visibility:inherit; top:0px; left:0px; height:'100%';width:'100%'; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';/"></iframe>";

}

......

}

OK现在在创建panel或者其子孙时我们只要设置一个属性

hasIframe: true,

就可以实现遮挡住OCX控件的功能了。




问题到了这里仿佛已经得到了完美的解决,但是当我们尝试着去拖动,或者拖曳这些窗口时有时你会发现一起很怪的现向,例如窗口扩大后有一部分无法遮挡住OCX控件,无法在OCX控件上面进行拖曳或者移动。

这是为什么呢?

第一个问题:为什么窗口的一部分可以挡住OCX控件呢?我明明把底层的iframe高度设置成了100%了!设置100%的意思是跟它外层的容器(这里是DIV)大小是一样的。 通过方法把最终的代码alert出来后才发现默认情况下它外层容器的高度是不显示出来的——为什么要这样设计,我也不知道。最简单的方法就是明确地给外层容器设置调度,并在拖曳时再给它们设置高度(panel的大小是不可以改变的,它的子类例如window是可以的)。OK那就再费点现设置一下吧。

第一步在panel实例化时设置一下高度

onRender : function(ct, position) {

……

this.el.dom.style.height=this.height; //高度

第二步在 window拖曳时改变一下容器调度

onResize : function(w, h) {

if(this.hasIframe) {

this.el.dom.style.height=h; //拖动的时候重新设置了高度



第二个问题: 在拖动层的过程中发现OCX又冒出来了,而且经过OCX时拖动就失败了。这时为什么呢?EXT拖动层时不是把层里面的所有元件(Elements)一起拖动,它只是拖动了最外层的容器,拖动结束后再在新位置上重新绘制元件——多好的设计呀,可惜在这里遇到了问题。那好吧,在拖动时把我们iframe也一起拖动不就OK了?

我们为

startDrag : function() {

………

if (this.win.hasIframe)

{

var newiframe= Ext.getDom(this.win.id+'_newiframe');

if (newiframe)

{

}

else

{

this.proxy.dom.innerHTML+="<iframe id='"+this.win.id+'_newiframe' +"' src=/"javascript:false/" style=/"position:absolute; visibility:inherit; top:0; left:0; width:100%; height:100%; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';/"></iframe>";

}

}

到这里前算是把拖曳问题解决的差不多了,为什么说是差不多了呢?你在实现使用时就会发现有点问题了。

第三个问题:在拖曳经过OCX时就变的无效了

这里不想说原因,说说解决方法吧。没找到更好的解决方法,现在的做法是在拖曳时让底层的iframe临时扩大的全屏,拖完以后再还原回来。

beforeResize : function() {

……

//拖动之前 把它的底层iframe 扩展到最大

if (this.hasIframe)

{

var divIframe=Ext.getDom(this.id+'_iframe');

divIframe.style.top=-2000;

divIframe.style.left=-2000;

divIframe.style.height=4000;

divIframe.style.width=4000;

}



},

handleResize : function(box) {

……

if(this.hasIframe) {

var divIframe= Ext.getDom(this.id+'_iframe');

divIframe.style.height='100%';

divIframe.style.width='100%';

divIframe.style.top=0;

divIframe.style.left=0;

divIframe.style.position='absolute';

this.el.dom.style.height=box.y; //拖动的时候重新设置了高度

}



},



后记:

1)

使用类似方方法我们可以解决 EXJS里面尽乎所有的DIV被OCX拦住的问题——笔都解决了菜单,面板,窗口,消息框

2)

当然我们可以能过 Ext.DomHelper.append方法把我们的代码写的优雅一点...。。

Ext.DomHelper.append(this.el.dom, {
tag : 'iframe',
id: iframeid,
style : "position:absolute; visibility:inherit; top:0; left:0; width:100%; height:100%; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'",
src : 'javascript:false'

})

如果在EXTJS实现,只需要加上一句全局开关

Ext.useShims =true

在创建各种window的时候加上一句全局开关Ext.useShims=true,给window加上属性shim=true(其实不用加,默认就是true)。
好了,只要一句Ext.useShims=true,就可以遮挡ActiveX了,原来这么简单,layer就是加shim,shadow的,这个shim我还以为是两端间隙,没想到是一个遮挡层。

所谓有现成的方法不用,就是傻蛋啊
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值