2010-12-13 18 views
8

Estoy tratando de escribir una opción de menú contextual para una página mía. Básicamente, se hace clic derecho en un div, aparece un menú de opciones que se puede usar para realizar tareas.jQuery menú contextual - encontrar qué elemento lo desencadenó

Mi problema es tratar de encontrar el elemento original que desencadenó todo (es decir, el div que se hizo clic derecho).

Mi código jQuery es más o menos:

//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> 

- Por lo tanto - Puedo ver qué elemento creado el evento inicial cuando el botón derecho del ratón pasa. Pero no cuando se hace clic en el elemento del menú.

Estaba trabajando en buscar algo a tientas escribiendo el elemento en un cuadro de texto oculto cuando se hace clic derecho, luego lo leo cuando se hace clic en una de las opciones, y luego lo quito cuando se cierra el menú. Aunque no parece el enfoque ideal, siento que me falta algo básico.

Espero que veas lo que estoy tratando de hacer. Puedo publicar un ejemplo más completo a pedido.

Respuesta

6

Se podría considerar el uso de los métodos de jQuery data storage.

En su código menú contextual se puede poner:

$('.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; 
}); 

Luego, cuando se desea hacer referencia al elemento que inició el clic, puede simplemente hacer esto:

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

Y poner originalElement en la función jQuery $() para acceder a la bondad jQuery. No importa dónde coloque los datos, ya que cualquier elemento DOM puede tener datos asociados. Puede almacenar cualquier cosa: en el código de ejemplo anterior, almaceno el HTMLElement en bruto (no jQueryified) pero puede almacenarlo también si lo desea.

Vea aquí un pequeño ejemplo: http://www.jsfiddle.net/jonathon/sTJ6M/

+1

Dos comentarios: 1. Está utilizando el motor selector para encontrar el elemento #contextMenu varias veces. Sería razonable almacenar en caché ese objeto jQuery: 'var $ contextMenu = $ (" # contextMenu ");' 2. Podría ser una buena idea evitar que 'originalElement' sea indefinido, en cuyo caso' originalElement.id' haría lanzar un error –

+1

Cheers Šime. Estoy de acuerdo con sus puntos, pero no estaba demasiado preocupado con la refactorización. Estaba insertando en el código del OP y dejando en claro cómo usar los métodos de datos. En esta instancia, en lugar de almacenar en caché el objeto, puede beneficiarse del encadenamiento y no requerir la variable adicional :) –

+0

¡Gracias Jonathon, eso es justo lo que necesitaba! –

2

agrego un campo oculto y luego se les hace en base al clic, así:

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

luego con jQuery

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

Es posible que desee mirar a los métodos de almacenamiento de datos - se ahorra tener que crear el tipo de entrada oculta para cosas como esta (y le permite guardar cualquier objeto, no sólo cadenas): http: //api.jquery.com/category/miscellaneous/data-storage/ –

+0

parece genial, pero el problema es ... se dispara cuando se hace un clic izquierdo ... +1 aunque :) –

+0

ese es el punto ¿no? – Jason

2

Estoy un poco tarde a la fiesta aquí, pero he encontrado que cuando se genera el menú contextual del elemento activo recibe la clase 'menú contextual-activa' añadido lo. Esto solo puede ser en versiones más recientes. Estoy usando el menú de contexto 1.6.6.

sólo tiene que añadir:

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

al controlador de menú contextual. Aquí se combina con el código de ejemplo.

$(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); 
    }) 
}); 
Cuestiones relacionadas