鸟食轩

 Microsoft .NET[C#] MVP 2003
随笔 - 424, 文章 - 231, 评论 - 5394, 引用 - 344
数据加载中……

在popup窗口中俘获事件的缺陷&修复

    我们在处理HTML元素的事件时,通常可以使用两种方法来添加其处理函数。一是直接向HTML元素的事件处理回调(如:onclick、onlond等)赋值;一是使用元素的attachEvent()方法来添加处理函数。这两种方法对于普通的页面表现出来的效果是完全相同的,而对于popup它们却有很大的差别。

    先看下面的popup中事件处理示例,再来说是什么问题:
<script language="javascript">
function NormalEventListener(elmt)
{
    alert(event);
}

function AttachEventListener(evt)
{
    alert(evt);
}

var popwin = window.createPopup();
var popdoc = popwin.document;
var div = popdoc.createElement('DIV');
div.style.width 
= '100%';
div.style.height 
= '100%';
div.style.border 
= 'dotted 1px blue';
div.innerText 
= 'click me.';
div.onclick 
= function Click()
{
    NormalEventListener(
this);
}
;
div.attachEvent('onclick', AttachEventListener);
popwin.document.body.appendChild(div);
popwin.show(
100100200200);
</script>

    这个示例中,分别使用了两种方法来添加事件处理函数。对于attachEvent这种方式,我在'使用Popup窗口创建无限级Web页菜单(3)'一文中介绍过它的用法,而且说明了怎么在其处理函数中获取全局事件变量event。就是被attach的处理函数的第一个参数即是默认的event变量。

    今天我无意中使用了另一种方法,向事件处理回调赋值的方法附加事件处理函数,div.onclick = function()。却发现了一个popup窗口中响应时间处理函数的缺陷。执行上面的代码,我们会发现NormalEventListener()方法的elmt参数是引发事件的元素本身的引用,而此时调用event属性,却发现event这厮居然是:null。这可咋怎呐?! 

    原来NoramlEventListener()中的event是window.event,因为这个函数定义在IE的window的作用域内,它的引用也可以写成window.NormalEventListener(),而我们触发的事件是在popup窗口中的window中。就是说IE的window和popwin.document.parentWindow是两个不同的域,当然这个时候window.event就是null了。解决这个问题的办法有两个,一可以去取popwin.document.parentWindow的event,不过这个方法比较麻烦,需要专门去记录那个popwin变量。另外还有一个最简单的方法可以取到正确的event属性。因为每个事件触发的源元素(srcElement)和触发它的事件属性总是在同一个域中,所以我们就可以使用如下办法将其取到:
 function NormalEventListener(elmt)
 {
    
var evt = elmt.document.parentWindow.event;
    alert(evt);
 }

    这个elmt参数是从Click函数中传递过来的触发事件的元素本身,即:event.srcElement。

posted on 2005-03-05 01:14 birdshome 阅读(6418) 评论(4)  编辑 收藏 所属分类: Jscript&Dhtml开发

评论

#1楼    回复  引用    

前段时间在写pop时也碰到这个问题后就全改成attachEvent了,当时就觉得elmt.document.parentWindow.event这样引用过于麻烦
2005-05-11 21:20 | edison1024 [未注册用户]

#2楼    回复  引用    

如果把函数定义和调用的onClick都写在一个popup窗口的body中,点击触发时找不到方法的定义,不知道是怎么回事.
2005-06-07 14:17 | wearebug [未注册用户]

#3楼 [楼主]   回复  引用  查看    

@wearebug
你怎么把脚本写到popup窗口里去的?我试了没有问题呀。
<html>
<body>
    
<script>
    
function fnRun(elmt)
    
{
        
var popup = window.createPopup();
        
var doc = popup.document;
        doc.write(
this.document.documentElement.outerHTML);
        doc.close();
        
        popup.show(
100100300300, elmt);
    }

    
</script>
    
<button onclick="fnRun(this)">
        Click
</button>
</body>
</html>
2005-06-07 15:29 | birdshome      

#4楼    回复  引用    

谢谢,我搞错了.我使用xmlhttp把另一个xml装载进来,然后给当前页的XXX.innerHTML赋值的,但是当前页面没有定义要调用的方法,是在那个xml文件中定义的.这个还是由于不同的域引起的问题.
2005-06-07 17:16 | wearebug [未注册用户]