5

我正在尝试向事件原型添加一个方法。为了调用/设置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;
    };
}

正如您在此处看到的那样,这似乎可行。这个小提琴显示OK在 IE8、firefox 和 chrome 中。虽然,当我将它添加到我的脚本时,IE8 在第一行中断,说'Event is undefined'。离开"use strict";根本没有区别。

不情愿地,我也尝试了这个:

if (typeof Event === 'undefined')
{
    var Event = window.Event || window.event;//FFS IE :-(
}

但无济于事:Error: 'Event.prototype' is null or not an object,所以我又得到了 1 行。问题是,整个原型方法是从我的脚本复制粘贴,但我在这里忽略了什么?有什么想法/建议吗?
谢谢

PS:我喜欢 Pure JavaScript,所以请不要建议使用 jQuery、prototypejs、dojo 等作为解决方案。我刚刚摆脱了 jQuery。(我喜欢 jQuery,但在这种情况下不需要它)


更新

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

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

它可以在页面下方约 3/4 的标题为 的部分中找到"Powerful Scenarios"。在我看来,这与我想做的事情完全相同,但更重要的是:如果我通过 jsfiddle 尝试此代码,它甚至都不起作用,而我的 jsfiddle(使用我的代码)确实可以在 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;
};
4

2 回答 2

3

我最近有(另一个)脑电波,我想我找到了一种更好的方法来增强事件原型。严格来说,Event原型在 IE 中是不可访问的(<9),但如果你从一个实例(嗯,实例:)返回,我发现它是可访问的window.event。所以这是一个适用于所有主要浏览器(和 IE8 - 而不是 7)的片段:

(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);
        }
})();

这样,标题文档类型就没有那么重要了:我已经使用<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">. 不过<!DOCTYPE html>为了安全起见

希望这可以帮助某人...

于 2012-06-26T10:03:13.323 回答
2

它的标准与怪癖模式。JSFiddle 页面有一个 DOCTYPE 声明,尽管是一个非常简单的声明,<!DOCTYPE html>它将渲染踢到标准模式。您的网页可能没有 DOCTYPE,这会使渲染处于 Quirks 模式。将那个简单的 DOCTYPE 添加到我从你的小提琴构建的页面后,它对我有用。

于 2012-05-21T13:35:10.557 回答