2

これが可能かどうか、または良いアイデアであるかどうかの答えを探しています。

通常、IE8 以前のバージョンの修正として、次のような回避策が使用されます。

var addEvent = function(obj, e, cb) {
    if(obj.attachEvent) {
        return obj.attachEvent('on' + e, cb);
    } else {
        obj.addEventListener(e, cb, false);
        return true;
    }
}

そして、プログラマーは常にaddEventの代わりに を使用しaddEventListenerます。

未定義のときにaddEventListenerラップする関数を作成する方法またはポイントはありますか?attachEvent

EventTarget は DOM 要素、ドキュメント、ウィンドウ、またはその他のものになる可能性があるため、少し注意が必要だと思います。

4

2 に答える 2

1

どこまで戻りたいかによります。IE8 では、拡張Element.prototypeしてすべての HTML 要素に機能を追加できますが、これは少なくとも作業の 90% です。IE6ではそれができないと確信しています(PrototypeJSは個々のElementインスタンスを拡張する必要がありました).IE7については覚えていません。ただし、東アジア市場をターゲットにしている場合を除き、IE7 以前は基本的に無視できます。

これを行う方法の例を次に示します。

(function() {
  // Functions for IE
  function stopPropagation() {
    this.cancelBubble = true;
  }
  function preventDefault() {
    this.returnValue = false;
  }
  function addEventUsingAttach(eventName, handler)
  {
    this.attachEvent("on" + eventName, function() {
      var e = window.event;
      e.stopPropagation = stopPropagation;
      e.preventDefault = preventDefault;
      handler.call(this, e);
    });
  }

  // Function to add `addEvent` to the given target object
  function extendIt(target)
  {
    if (target.addEventListener) {
      target.addEvent = Element.prototype.addEventListener;
    }
    else {
      target.addEvent = addEventUsingAttach;
    }
  }

  // Add it to `Element.prototype` if we have it
  if (typeof Element !== "undefined" &&
      typeof Element.prototype !== "undefined") {
    extendIt(Element.prototype);
  }

  // Add it to `window` and `document` (etc.)
  extendIt(window);
  extendIt(document);
})();

実例| ソース

window次に、やなどの他の EventTarget を手動で拡張しますdocument(上記のコード リストの最後を参照)。


元の回答:私はもともとあなたの質問をaddEventListener、具体的にはIE8で追加することについて誤解していましたが、実際にはあなたの質問はそれを追加することではなく、独自のaddEvent. 私は他の読者のためにこの答えを残しておきます:

どこまで戻りたいかによります。IE8 では、拡張Element.prototypeして追加できaddEventListenerます。これは、ページ上のすべての HTML 要素で使用されます (以下を参照)。ただし、追加する shim はキャプチャ フェーズをサポートできません。これは、IE がaddEventListenerネイティブでサポートされるまでサポートしていなかったためです。Element.prototype以前のバージョン (IE7、IE6) では拡張できないことは確かです。PrototypeJS は、古いバージョンの IE の特定の要素を拡張するようにフォールバックする必要がありました。しかし、IE8で動作します。

を拡張Element.prototypeした後、言及した他のイベント ターゲットを手動で拡張する必要がありますが、拡張によってElement.prototypeほとんどの作業が行われます。

ただし、これを行い、サードパーティのスクリプトを含める場合はaddEventListeneer、キャプチャ フェーズを含む完全な実装が正しく行われていると見なされる可能性があることに注意してください。

addEventListenerIE8に追加するための基本的な shim は次のとおりです。

(function() {
  function stopPropagation() {
    this.cancelBubble = true;
  }
  function preventDefault() {
    this.returnValue = false;
  }
  if (typeof Element !== "undefined" &&
      typeof Element.prototype !== "undefined" &&
      !Element.prototype.addEventListener) {
    Element.prototype.addEventListener = function(eventName, handler, useCapture) {
      if (useCapture) {
        throw "Browser doesn't support capturing phase";
      }
      this.attachEvent("on" + eventName, function() {
        var e = window.event;
        e.stopPropagation = stopPropagation;
        e.preventDefault = preventDefault;
        handler.call(this, e);
      });
    };
  }
})();

実例| ソース

于 2013-10-27T10:07:36.007 に答える
0

一般に、関数をオブジェクトにアタッチすることで、オブジェクトに関数を追加できます。

obj.addEventListener = function(/* args*/) { /* body */ }

または、関数をオブジェクト コンストラクターのプロトタイプにアタッチすることによって

EventTarget.prototype.addEventListener = function(/* args*/) { /* body */ }

前者では、追加された関数を特定のオブジェクトでのみ呼び出すことができますが、後者では、その特定のオブジェクト コンストラクターから作成される、または作成されるすべてのオブジェクトで関数を呼び出すことができます。

でも、

  • EventTarget はホスト オブジェクトであるため、そのようなオブジェクトに関数を追加できるかどうかは実装に依存します。
  • EventTargets はホスト オブジェクトであるため、EventTarget.prototype実際に存在し、ネイティブ オブジェクトと同じ意味を持つかどうかは実装に依存します。
  • オブジェクトがEventTargetインターフェースに準拠している場合、おそらく既にaddEventListener機能を持っています。
  • でアタッチされたイベント リスナにattachEventは、 で追加されたものとは異なる引数がありaddEventListenerます。

最終的に、JavaScript を使用して、安っぽい DOM サポートを備えたブラウザーをより多くの標準に準拠させようとすることは現実的ではありません。

于 2013-10-27T10:14:48.443 に答える