2010-12-13 9 views
8

Sto cercando di scrivere un'opzione del menu di scelta rapida per una mia pagina. Fondamentalmente si fa clic con il tasto destro su un div, si apre un menu di opzioni che può essere utilizzato per eseguire attività.menu di scelta rapida di jQuery: trovare l'elemento che lo ha attivato.

Il mio problema è cercare di trovare l'elemento originale che ha attivato tutto (ovvero il div che è stato fatto clic con il pulsante destro del mouse).

Il mio codice jQuery è più o meno:

//this is what displays the context menu 
$('.outfeedPosition').bind("contextmenu", function (e) { 
    $('#contextMenu').css({ 
     top: e.pageY + 'px', 
     left: e.pageX + 'px' 
    }).show(); 

    //'this' is the element which was clicked by the user. 
    alert($(this).attr('id')); 

    return false; 
}); 



//this is the contextMenu's button handler. 
$('#ctxDelete').click(function() { 
    alert('delete was clicked, but i dont know by which element - so I dont know which one to delete'); 
}); 


<div id="contextMenu"> 
    <ul> 
     <li><a id="ctxInsert" href="#">Insert</a></li> 
     <li><a id="ctxEdit" href="#">Edit</a></li> 
     <li><a id="ctxDelete" href="#">Delete</a></li> 
    </ul> 
</div> 

- Così - posso vedere quale elemento ha creato l'evento quando il primo pulsante destro del mouse accade. Ma non quando si fa clic sulla voce di menu.

Stavo lavorando per armeggiare qualcosa insieme scrivendo l'elemento in una casella di testo nascosta quando si fa clic con il pulsante destro del mouse, quindi leggendolo quando si fa clic su una delle opzioni, quindi rimuovendolo quando il menu si chiude. Non sembra però l'approccio ideale - e mi sento come se mi mancasse qualcosa di base.

Spero che tu veda quello che sto cercando di fare. Posso pubblicare un esempio più completo su richiesta.

risposta

6

Si potrebbe considerare l'utilizzo di metodi di jQuery data storage.

Nel codice menu di contesto si può mettere:

$('.outfeedPosition').bind("contextmenu", function (e) { 
    $('#contextMenu').css({ 
     top: e.pageY + 'px', 
     left: e.pageX + 'px' 
    }).show(); 

    //Store the item that was clicked 
    $("#contextMenu").data('originalElement', this); 

    return false; 
}); 

Poi, quando si desidera fare riferimento all'elemento che ha avviato il clic, si può solo fare questo:

$('#ctxDelete').click(function() { 
    var originalElement = $("#contextMenu").data('originalElement'); 
    alert('delete was clicked by ' + originalElement.id); 
}); 

E mettere originalElement in la funzione jQuery $() per accedere alla qualità jQuery. Non importa dove si inseriscono i dati, poiché ogni elemento DOM può avere dati associati ad esso. È possibile memorizzare qualsiasi cosa: nel codice di esempio sopra, memorizzo il raw HTMLElement (non jQueryified) ma è possibile memorizzarlo anche se lo si desidera.

vedi qui per un piccolo esempio: http://www.jsfiddle.net/jonathon/sTJ6M/

+1

Due osservazioni: 1. Si sta utilizzando il motore di selezione per trovare l'elemento #contextMenu più volte. Sarebbe ragionevole memorizzare nella cache l'oggetto jQuery: 'var $ contextMenu = $ (" # contextMenu ");' 2. Potrebbe essere una buona idea evitare che 'originalElement' non sia definito, nel qual caso' originalElement.id' sarebbe lanciare un errore –

+1

Cheers Šime. Sono d'accordo con i tuoi punti, ma non ero troppo interessato al refactoring. Stavo solo inserendo il codice OP e chiarendo come utilizzare i metodi dati. In questo caso, invece di memorizzare l'oggetto nella cache, puoi trarre vantaggio dal concatenamento e non richiedere la variabile extra :) –

+0

Grazie Jonathon, questo è proprio quello di cui avevo bisogno! –

2

posso aggiungere un campo nascosto e poi trovo sulla base del click, in questo modo:

<div class="myItem"> 
    <div id="contextMenu"> 
     <ul> 
      <li><a id="ctxInsert" href="#">Insert</a></li> 
      <li><a id="ctxEdit" href="#">Edit</a></li> 
      <li><a id="ctxDelete" href="#">Delete</a></li> 
     </ul> 
    </div> 
    <input type="hidden" class="myID" value="1"> 
</div> 

poi con JQuery

$('#ctxDelete').click(function() { 
    var id = $(this).closest('.myItem').find('.myID').val(); 
    alert('delete was clicked, by element with ID = ' + id); 
}); 
+0

Si potrebbe desiderare di guardare i metodi di archiviazione dei dati - si evita di dover creare il tipo di input nascosto per cose come questa (e consente di salvare qualsiasi oggetto, non solo le stringhe): http: //api.jquery.it/category/miscellanea/data-storage/ –

+0

sembra interessante, ma il problema è che si attiva quando si fa clic con il tasto sinistro del mouse .. +1 però :) –

+0

questo non è vero? – Jason

2

Sono un po 'in ritardo alla festa qui, ma ho scoperto che quando viene generato il menu contestuale la voce attiva ottiene la classe 'menu contestuale-attivo' aggiunto ad esso. Questo potrebbe essere solo nelle versioni più recenti. Sto usando il menu contestuale 1.6.6.

Basta aggiungere:

var originalElement = $('.context-menu-active'); 

al gestore di menu di scelta rapida. Qui è combinato con il codice di esempio.

$(function(e){ 
    $.contextMenu({ 
     selector: '.context-menu-one', 
     callback: function(key, options) { 
      var originalElement = $('.context-menu-active'); 
      var m = "clicked: " + originalElement[0].innerHTML; 
      window.console && console.log(m); 
     }, 
     items: { 
      "edit": {name: "Edit"}, 
      "cut": {name: "Cut"}, 
      "copy": {name: "Copy"}, 
      "paste": {name: "Paste"}, 
      "delete": {name: "Delete"}, 
      "sep1": "---------", 
      "quit": {name: "Quit"} 
     } 
    }); 

    $('.context-menu-one').on('click', function(e){ 
     console.log('clicked', this); 
    }) 
});