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

あなたがここで見ることができるように、これはうまくいくようです。このフィドルはOKIE8、Firefox、Chromeで表示されます。ただし、これをスクリプトに追加すると、IE8は最初の行で「イベントは未定義です」と中断します。除外し"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はそれほど重要ではありません。私は<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">、を使用してテストしました。FF、chrome、IE 8で動作し、問題はありません。<!DOCTYPE html>安全のために使用しますが

これが誰かを助けることを願っています...

于 2012-06-26T10:03:13.323 に答える
2

その標準対クァークズモード。JSFiddleページにはDOCTYPE宣言がありますが、これは非常に単純なもの<!DOCTYPE html>ですが、レンダリングを標準モードにキックします。WebページにDOCTYPEがないため、レンダリングがQuirksモードのままになる可能性があります。私があなたのフィドルから作成したページにその単純なDOCTYPEを追加した後、それは私のために働きました。

于 2012-05-21T13:35:10.557 に答える