2010-12-11 11 views
1

私は困惑し続けます。私にとってはうまくいくコンテキストメニューを見つけることができません。多分誰かが助けることができますか?ブラウザのcontextmenuイベントにフックする方法

は、ここで私はのcontextMenuをに追加する必要があるものにです:これは動的なリストである

<ul id="list_{id}" class="list"> 
    <li id="Item_{id}"><a ondblclick=""><span>{title}</span></a></li> 
</ul> 

、それがページ上でそれらの多くの多くを追加し、それらを異なるIDを与えることによって異なるので。ですから、私はすべてのリストに追加されるcontextMenuが必要ですが、各リストに対して一意のcontextMenuが追加されます。 contextMenuのIDなどにdynamic {id}タグを追加することで、すべてのリストのcontextMenuの基本的に異なるインスタンスです。

おかげ

+1

あなたは、コンテキストメニューとはどういう意味ですか?ページを右クリックすると表示されるコンテキストメニューはブラウザに提供され、変更することはできません。ただし、ブラウザがこれを表示しないようにして、代わりに「偽の」コンテキストメニューを表示することができます。この場合、複数のコンテキストメニューを作成するのではなく、クリックした要素に応じて内容を変更する1つのコンテキストメニューを作成します。 –

+0

私は右クリックメニューを意味し、ページ上の各 "ul"要素はそれ自身のコンテキストメニューを持っていなければなりません。ですから、 "list_ {id}"のIDを持つリストをクリックすると、 "{someFunction}"というコンテキストメニューが表示されます。 – Yan

答えて

6

それはあなたが求めているものを伝えるのは難しいのようなものだが、あなたは、ブラウザの「コンテキストメニュー」イベントにフックしたい場合、あなたはcontextmenuイベントをフックして、あなたがしているものは何でも(たとえば、divを作成することを含めることができます。例えば、その上のオプション  —、あなた自身のコンテキストメニュー)。あなたはあなたの質問に示された通りgetElementByIdを介してリスト自体に個別に行うこともできますし、すべてのリストを保持しているコンテナにイベントをフックして、イベントがいつトリガされたかを把握することもできますそれがトリガされたリスト(「イベント委任」)。

イベント委任アプローチについては、この回答の最後を参照してください。しかし、あなたが使用した実際のIDを知る方法を持っているとあなたには、いくつかの理由のために特別に各リストをフックしたいと仮定すると:

HTML:

<ul id='list_1'> 
    <li>List 1 item 1</li> 
    <li>List 1 item 2</li> 
</ul> 
<ul id='list_2'> 
    <li>List 2 item 1</li> 
    <li>List 2 item 2</li> 
</ul> 

ではJavaScript:

hookEvent(document.getElementById('list_1'), 'contextmenu', function(event) { 
    event = event || window.event; 
    if (event.preventDefault) { 
    event.preventDefault(); 
    } 
    display("List 1 context menu"); 
    return false; 
}); 
hookEvent(document.getElementById('list_2'), 'contextmenu', function(event) { 
    event = event || window.event; 
    if (event.preventDefault) { 
    event.preventDefault(); 
    } 
    display("List 2 context menu"); 
    return false; 
}); 

function hookEvent(element, event, handler) { 
    if (element.addEventListener) { 
    element.addEventListener(event, handler, false); 
    } 
    else if (element.attachEvent) { 
    element.attachEvent('on' + event, handler); 
    } 
    else { 
    element['on' + event] = handler; 
    } 
} 

Live example

一部の(ほとんどの)ブラウザだけがデフォルトのコンテキストメニューをキャンセルできることに注意してください。


更新:あなたの "?しかし、どのようなIDがバインド可能であるならば、" 再以下の質問:私はあなたが "バインディング可能"とは何を意味するのか分かりません。恐れ入りますが  —あなたの質問のタグはどれも特定のテンプレート技術を示していません。テンプレート化がサーバー側で起こっているのか、クライアント側で起こっているのかについても言及していません。しかし、基本的に、JavaScriptが実行されるときには、ドキュメントの実際の要素に実際のIDが存在します。 getElementByIdを使用するには、これらのIDが何であるかを知る必要があります。

サーバー側のテンプレート

これらのIDは完全に動的であることを行っていると、テンプレートは、サーバー上で処理されている場合は、JavaScriptににこれらのIDを渡し、スクリプトの小さなビットを含めることができます。たとえば、ドキュメントの上部付近には、次のようなものがあります。

<script type='text/javascript'> 
var mySpecialListIDs = []; 
</script> 

...その後、小さなscriptタグにそれが展開されるたびに追加するにはテンプレートを更新:

<ul id="list_{id}" class="list"> 
    <li id="Item_{id}"><a ondblclick=""><span>{title}</span></a></li> 
</ul> 
<script type='text/javascript'> 
mySpecialListIDs.push("{id}"); 
</script> 

次に、あなたのクライアント側のコードループmySpecialLitIDs通過できるとハンドラをフックする場合、各IDを使用します。

クライアント側のテンプレート

テンプレートは、これは少しシンプルな取得、クライアント側で行われている場合:ちょうどあなたのクライアントサイドスクリプトでいくつかの便利な場所であなたのmySpecialListIDsリストを設定し、あなたがテンプレートエンジンを呼び出すたびにそれに追加してください。


イベント委任:あなたはこのような動的なリストを持っているとしている場合は、サーバ - またはクライアント側のテンプレートをやっているかどうか、時々イベント委任がそれを処理するための最良の方法です。 contextmenuイベント(すべてではありませんが、ほとんどのイベントと同様)バブル DOMを上にします。したがって、祖先要素(ドキュメント本体自体のようなすべてのリストを含むもの)にフックすると、イベントオブジェクトを調べることによってクリックされた実際のリストを見ることができます。このように:

HTML:

<div id='list_container'> 
    <ul id='list_1'> 
    <li>List 1 item 1</li> 
    <li>List 1 item 2</li> 
    </ul> 
    <ul id='list_2'> 
    <li>List 2 item 1</li> 
    <li>List 2 item 2</li> 
    </ul> 
</div> 

のJavaScript(上からhookEvent機能を使用して):

// Hook up the contextmenu event on the container, not 
// on each list: 
hookEvent(document.getElementById('list_container'), 
      'contextmenu', 
      handleListContextMenu); 

// Our handler function 
function handleListContextMenu(event) { 
    var target; 

    // Handle IE-vs-the-world difference 
    event = event || window.event; 

    // Find out what the actual target element clicked was 
    target = event.target || event.srcElement; 

    // See if it or an ancestor of it is one of our lists 
    while (target && 
     (target.tagName !== "UL" || !target.id || target.id.substring(0, 5) !== "list_")) { 
    target = target.parentNode; 
    } 

    // Did we find a list? 
    if (target) { 
    // Yes, handle this. 
    if (event.preventDefault) { 
     event.preventDefault(); 
    } 
    display("List '" + target.id + "' context menu"); 
    return false; 
    } 
} 

Live example

+0

しかし、私のIDがバインド可能({id})の場合、どうすればgetElementByIdを使って見つけることができますか? – Yan

+0

@ヤン:私はあなたが "バインディング可能"とは何を意味するのか分かりません。質問のタグはどれも特定のテンプレート技術を示していません。テンプレート化がサーバー側で起こっているのか、クライアント側で起こっているのかについても言及していません。しかし、私は、いくつかの拠点をカバーし、私が本当に*本来述べていたはずのオプション(イベント委任)を提供するための答えを更新しました。それと幸運。 –

+0

これはサーバー側のテンプレートです。コンテキストメニューであなたが提供したものを使用することによって、 "getElementById( 'mySpecialListIDs')"と記述する必要があります。 – Yan

関連する問題