0

画像が右クリックされた場合にアクティブになるコンテキストメニュー項目があります。これは、アクティブになるのとまったく同じ方法です'context-copyimage'

そのメニュー項目を に関連付け/ペアリングすることで'context-copyimage'、余分な (重複した) イベントリスナーと表示/非表示ハンドラーを追加する必要がなくなりますか??!!
(オブザーバーを追加'context-copyimage'して目的を無効にする)

そうでない場合、使用するイベントリスナーを使用することは可能'context-copyimage'ですか?

更新:
リスナーを削減しようとしています。現時点では、スクリプトにはpopupshowingリスナーがあります。popupshowingでは、チェックしgContextMenu.onImagて true の場合、メニュー項目を表示します。Firefoxcontext-copyimageもまったく同じことを行います。スクリプト内のイベントリスナーを削除/削減するために、これら2つを結び付けることができるかどうか疑問に思っていました.

私もダガーとおしゃべりをしていて、彼はこう言いました:

... 組み込みアイテムの状態はイベント ハンドラから設定されず、nsContextMenu のコンストラクタから設定され、それにフックするメカニズムはありません。

どうやら、それは不可能です

4

2 に答える 2

3

いいえ、別のイベント リスナーよりも優れたパフォーマンスを発揮し、セッションでのアドオンのアンロードと互換性のあるイベント リスナーを回避する適切な方法はありません。

フッキングnsContextMenu

既に述べたように、状態は を介し​​て初期化されgContextMenu = new nsContextMenu(...)ます。そのため、フックする必要がありますが、これは実際には非常に簡単です。

var newProto = Object.create(nsContextMenu.prototype);
newProto.initMenuOriginal = nsContextMenu.prototype.initMenu;
newProto.initMenu = function() {
    let rv = this.initMenuOriginal.apply(this, arguments);
    console.log("ctx", this.onImage, this); // Or whatever code you'd like to run.
    return rv;
};
nsContextMenu.prototype = newProto;

さて、最初の質問は、実際にパフォーマンスが向上するかどうかです。結局のところ、これはプロトタイプチェーンに別のリンクを導入しただけです。もちろん、回避Object.createして直接オーバーライドすることもできますnsContextMenu.prototype.initMenu

しかし、本当の問題は次のとおりです。フックを再び削除するにはどうすればよいでしょうか。回答: 他のアドオンがあなたの後に同じものをフックした可能性があり、フックを解除すると他のアドオンもフック解除されるため、実際にはできません。ただし、参照を削除する必要があります。削除しないと、アドオンを無効化/アンインストールしたときにメモリ リークが発生します。まあ、あなたは と戦うことができますがComponents.utils.makeObjectPropsNormal、それは閉ざされた変数にはあまり役に立ちません。では、クロージャーは避けましょう...うーん...イベントリスナーやオブザーバーなど、何らかのメッセージが必要になるでしょう...そして振り出しに戻ります。

また、私はこれを正気とは呼びません

document.getElementById("contentAreaContextMenu").addEventListener(...)

私はそれを「測定可能な利益のないやり過ぎ」と呼んでいます。

オーバーライドonpopupshowing=

をオーバーライドできます<menupopup onpopupshowing=。ええ、それは飛ぶかもしれません...他のアドオンが同じ考えを持っているかもしれないことを除いて、互換性地獄へようこそ. また、これには再びウィンドウへのプッシュが含まれます。これにより、クロスコンパートメント ラッパーが発生し、エラーが発生しやすくなります。

これは解決策ですか?たぶん、しかし正気ではありません。

ほかに何か?

それほど多くはありません。

于 2014-07-11T09:57:09.433 に答える
1

はい、これは絶対に可能です。mozillazine の Morat がここで素晴らしい解決策を提供してくれました:

function handleClick(event) {
  window.removeEventListener("click", handleClick, true);
  event.preventDefault();
  event.stopPropagation();
  var node = document.popupNode;
  document.popupNode = event.originalTarget;
  var menuPopup = document.getElementById("contentAreaContextMenu");
  var shiftKey = false;
  gContextMenu = new nsContextMenu(menuPopup, shiftKey);
  if (gContextMenu.onImage) {
    var imgurl = gContextMenu.mediaURL || gContextMenu.imageURL;
  }
  else if (gContextMenu.hasBGImage && !gContextMenu.isTextSelected) {
    var imgurl = gContextMenu.bgImageURL;
  }
  console.log('imgurl = ', imgurl)
  document.popupNode = node;
  gContextMenu = null;
}
window.addEventListener("click", handleClick, true);

gContextMenuこれにより、リンク上にいる場合、画像を右クリックした場合、およびgContextMenu.imageURLその値を保持している場合など、あらゆる種類のプロパティを持つにアクセスできます。クール

このコードはコンソールログimgurlに記録されます。イメージを超えていない場合はログに記録されますundefined

于 2014-07-11T09:33:05.887 に答える