WEB开发上面DIV层被OCX控件拦住有关问题的解决思想,以及结合EXTJS的解决办法
WEB开发下面DIV层被OCX控件拦住问题的解决思想,以及结合EXTJS的解决方法
公司开发的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我还以为是两端间隙,没想到是一个遮挡层。
所谓有现成的方法不用,就是傻蛋啊
公司开发的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我还以为是两端间隙,没想到是一个遮挡层。
所谓有现成的方法不用,就是傻蛋啊