IE8中的JavaScript事件原型

IE8中的JavaScript事件原型,javascript,internet-explorer-8,prototype,dom-events,Javascript,Internet Explorer 8,Prototype,Dom Events,我正在尝试向事件原型添加一个方法。为了调用/设置preventDefault()或在IE中调用returnValue=false和-如果需要-stopPropagation()/cancelBubble=true。我想下面的代码就足够了 Event = Event || window.Event; //^^ makes the fiddle work on IE8 ^^ if(!(Event.prototype.stopEvent)) { Event.prototype.stopEven

我正在尝试向事件原型添加一个方法。为了调用/设置
preventDefault()
或在IE中调用
returnValue=false
和-如果需要-
stopPropagation()
/
cancelBubble=true。我想下面的代码就足够了

Event = Event || window.Event;
//^^ makes the fiddle work on IE8 ^^
if(!(Event.prototype.stopEvent))
{
    Event.prototype.stopEvent = function(propagate)
    {
        "use strict";
        propagate = (propagate ? true : false);
        if (this.preventDefault)
        {
            this.preventDefault();
            if (propagate === false)
            {
                this.stopPropagation();
            }
        }
        else
        {
            this.returnValue = false;
            this.cancelBubble = !propagate;
        }
        return this;
    };
}
这似乎有效。这把小提琴在IE8、firefox和chrome中显示
OK
。不过,当我将其添加到脚本中时,IE8在第一行中断,说“事件未定义”。省略
“严格使用”没有任何区别

我也不情愿地试了一下:

if (typeof Event === 'undefined')
{
    var Event = window.Event || window.event;//FFS IE :-(
}
但没有用:
错误:“Event.prototype”为null或不是对象,所以我又得到了一行。问题是,整个原型方法都是从我的脚本复制粘贴的,但我在这里忽略了什么?有什么想法/建议吗
谢谢

PS:我喜欢纯JavaScript,所以请不要建议使用jQuery、prototypejs、dojo,。。。作为解决办法。我刚刚摆脱了jQuery。(我喜欢jQuery,但在本例中不需要它)


更新

恐怕情况变得更糟了。我找到了。整个页面处理DOM元素原型。公平地说,它们在IE8中是可用的(在某种程度上)。在这一页上,以下代码引起了我的注意:

Event.prototype.stopPropagation = function ()
{
  this.cancelBubble = true;
};
Event.prototype.preventDefault = function ()
{
  this.returnValue = false;
};
可以在页面下方约3/4的标题为
“强大场景”的部分中找到它。在我看来,这与我想做的完全一样,但更重要的是:如果我通过JSFIDLE尝试此代码,它甚至不起作用,而我的JSFIDLE(以及我的代码)在IE8上确实起作用。这只是代码片段的最后几行,但据我所知,这几行代码应该可以正常工作。我对它们做了如下修改:

Event.prototype.stopPropagation = function ()
{
    if (this.stopPropagation)
    {
        return this.stopPropagation();
    }
    this.cancelBubble = true;
};
Event.prototype.preventDefault = function ()
{
    if (this.preventDefault)
    {
        return this.preventDefault();
    }
    this.returnValue = false;
};

它的标准与怪癖模式。JSFiddle页面有一个DOCTYPE声明,尽管它非常简单,
,可以将呈现模式转换为标准模式。很可能您的网页没有DOCTYPE,这会使呈现处于怪癖模式。在将这个简单的DOCTYPE添加到我用你的小提琴构建的页面后,它对我很有用。

我最近有了(另一个)脑波,我想我找到了一个更好的方法来扩展事件原型。严格来说,
事件
原型在IE中是不可访问的(您缺少的是主机对象不需要实现任何类型的继承,更不用说原型继承了。即使它们实现了,您也不能期望对它们进行修改。此外,IE 8实现了一些这样的功能,但只在标准模式下实现,而不是在怪癖模式下实现。因此,在IE 8和其他不使用im的浏览器之前,一般的解决方案被排除在外DOM对象的plement prototype继承不再使用。这可能需要一段时间。这仍然不能解释为什么相同的代码在我设置的fiddle中工作,但在我的页面上没有。除了IE8之外,所有浏览器都可以正常工作,IE8不在怪癖模式下运行。如果直接访问生成的框架,它仍然可以工作吗?(对不起,我没有IE8可供我在ATM机上进行自我测试)@gryzzly:是的,它在那里也很好。即使在兼容模式下。我根本无法解决它。我尝试过设置一个。这在IE8:-S中也很有效,即使我直接访问框架。我的实际建议是不要受影响,用自己的命名空间包装事件功能,并在那里委托逻辑(jQuery和其他人所做的),然而,很有趣的是,为什么会发生这种情况呢?顺便说一句,我正在偷它们!:)我的页面确实有doctype,但不是HTML5符号。页面仍然以标准模式呈现,但不知何故IE8切换回了IE7兼容模式。然而,切换到HTML5 doctype似乎确实有效。我认为他们会将IE踢进怪癖模式,而不是标准模式……很好,谢谢为后面的人提供一个快速提示;您可以通过检查
document.compatMode
属性来检测页面的呈现模式。值“CSS1Compat”是标准模式,其他任何值(包括null)都不是。
(function()
{
        function ol(e)
        {//we have an event object
            e = e || window.event;
            if (!e.stopEvent)
            {
                if (Object && Object.getPrototypeOf)
                {//get the prototype
                    e = Object.getPrototypeOf(e);
                }
                else
                {//getting a prototype in IE8 is a bit of a faff, this expression works on most objects, though
                 //it's part of my custom .getPrototypeOf method for IE
                    e = this[e.constructor.toString().match(/(function|object)\s+([A-Z][^\s(\]]+)/)[2]].prototype;
                }
                e.stopEvent = function(bubble)
                {//augment it (e references the prototype now
                    bubble = bubble || false;
                    if (this.preventDefault)
                    {
                        this.preventDefault();
                        if (!bubble)
                        {
                            this.stopPropagation();
                        }
                        return this;
                    }
                    this.returnValue = false;
                    this.cancelBubble = !bubble;
                    return this;
                };
            }
            alert(e.stopEvent ? 'ok' : 'nok');//tested, it alerts ok
            if (this.addEventListener)
            {
                this.removeEventListener('load',ol,false);
                return;
            }
            document.attachEvent('onkeypress',function(e)
            {
                e = e || window.event;
                if (e.stopEvent)
                {//another event, each time alerts ok
                    alert('OK!');
                }
            });
            this.detachEvent('onload',ol);
        }
        if (this.addEventListener)
        {
            this.addEventListener('load',ol,false);
        }
        else
        {
            this.attachEvent('onload',ol);
        }
})();