2012-03-23 12 views
6

Nunca me encuentro con esto antes ¿alguien me puede dar alguna indicación?jQuery stopPropagation()?

Estoy creando una aplicación web para tomar notas, como publicar notas en una pizarra. En este momento, el botón spawn generará notas, pero quiero hacerlo de modo que el usuario pueda hacer clic en cualquier parte del lienzo (pizarra) y generará una nueva nota en esa posición.

Este es el código para que: -

$("#canvas").bind('click', function(e){ 

// Calculate offset for width, put box to the left top corner of the mouse click. 
    var x = e.pageX + "px"; 
    var y = e.pageY + "px"; 

$("#note").clone().insertBefore("#insertAfter").attr("id", "note" + noteID).show(); 
    $("#note" + noteID).children(".title").text("Note " + noteID); 
     $("#note" + noteID).css({left:x, top:y, "z-index" : zindex}); 

    noteID++; 
    zindex++; 

e.preventDefault(); 
e.stopPropagation(); 
e.stopImmediatePropagation(); 

}); 

El problema surge cuando el usuario hace clic en una de las notas, porque las notas se clonan en el lienzo cada vez que el usuario hace clic en la nota de su creación otra nota. Quiero detener este comportamiento y SÓLO crear una nota cuando un usuario hace clic en un área de lienzo en blanco. He intentado prevenirDefantly, stopPropagation y stopImmediate ... pero ninguno de ellos parece tener ninguna influencia.

También los he probado en otras acciones, como el clic de la nota, pero parece que no puede encontrar la correcta en el lugar correcto. o estoy yendo sobre esto completamente de la manera incorrecta?

ejemplo aquí:

http://www.kryptonite-dove.com/sandbox/animate

ACTUALIZACIÓN:

$('#canvas').on('click', '.note', function(e) { 
    e.stopPropagation(); 
}); 

Esto resolvió el problema de las notas burbujeando sin embargo, ahora impide cualquier acción clic en la clase de nota, estoy en aguas inexploradas aquí! agradecería cualquier sugerencia sobre cómo hacer que las acciones de clic vuelvan a funcionar para el título y el texto de la nota :)

Respuesta

12

Si usted quiere hacer algo al pulsarlo #canvas, pero sólo si el clic directamente sobre #canvas y no en sus hijos, entonces las dos principales opciones disponibles para usted son:

  1. De acuerdo con su actualización, puede manejar el clic en cada elemento secundario y detener su propagación hasta el #canas, pero por supuesto eso complica el procesamiento que podría desear para los niños.

  2. Pruebe event.target property para ver si el elemento DOM que inició el evento es su elemento #canvas.

Así, observando también que (no relacionada con el problema en cuestión) que puede y debe cadena métodos jQuery en lugar de volver a seleccionar el mismo elemento:

$("#canvas").bind('click', function(e){ 

    // if the clicked element wasn't #canvas return immediately 
    if (e.target != this) 
     return; 

    // Calculate offset for width, put box to the left top corner of the mouse click. 
    var x = e.pageX + "px"; 
    var y = e.pageY + "px"; 

    $("#note").clone().insertBefore("#insertAfter") 
        .attr("id", "note" + noteID) 
        .css({left:x, top:y, "z-index" : zindex}) 
        .show() 
        .children(".title").text("Note " + noteID); 

    noteID++; 
    zindex++; 

    // You may not need any of the following any more (depending on 
    // what your other requirements are) 
    e.preventDefault(); 
    e.stopPropagation(); 
    e.stopImmediatePropagation(); 

}); 

He aquí una demostración (con una versión muy reducida de sus JS, básicamente, sólo la función de esta respuesta y sus estilos): http://jsfiddle.net/H6XrW/

(Tenga en cuenta que no siempre tiene que llamar tanto de .stopImmediatePropagation() y .stopPropagation() ya que el primero llama implícitamente el último para usted)

+0

Brillante gracias! gran explicación, código condensado y JS violín te dieron la victoria :) – KryptoniteDove

+0

Splendid! if (e.target! = this) return; ¡trabajos! – saike

1

Deberá detener la propagación al hacer clic en las notas, para que el elemento #canvas no se notifique cuando uno de sus hijos se hace clic (supongo que #insertAfter es un hijo de #canvas). Adjuntar un controlador de clic para cada nueva nota, que impide que el evento desde burbujeando:

$("#note" + noteID).click(function (e) { 
    e.stopPropagation(); 
}); 
+0

han intentado todo lo anterior y con vivo pero no alegría, las notas todavía están saliendo, más ideas? – KryptoniteDove

3

Este código se detendrá clics en las notas de la creación de nuevas notas:

$("#canvas").bind('click', function(e){ 

// Calculate offset for width, put box to the left top corner of the mouse click. 
    var x = e.pageX + "px"; 
    var y = e.pageY + "px"; 

    $("#note").clone().insertBefore("#insertAfter").attr("id", "note" + noteID).show(); 
    $("#note" + noteID).children(".title").text("Note " + noteID); 
    $("#note" + noteID).css({left:x, top:y, "z-index" : zindex}); 

    noteID++; 
    zindex++; 
}); 

$('#canvas').on('click', '.note', function(e) { 
    e.stopPropagation(); 
}); 

Funciona al detener los clics en las notas de la propagación hasta el lienzo div.

+0

Esto funciona para detener la propagación, ¡lo cual es GRANDE, gracias! :) sin embargo ... cada otra acción de clic en la nota tampoco funciona ahora. ¡Siento que se está uniendo, pero todavía falta algo! – KryptoniteDove

+0

Si está asumiendo que existe la clase 'note', entonces probablemente debería decirlo. De lo contrario, este enfoque es una versión más elegante de mi ejemplo simplificado. +1! – jwueller

+0

@elusive Comprobé el ejemplo que contiene la clase de nota. –

0

Soy un poco jquery noob, así que puede haber una forma más ordenada de hacerlo, pero he probado lo siguiente y me funciona. Me interesaría saber de otros si hubiera podido hacer algo mejor. No toqué el HTML o CSS.

// ----------------- BRING TO FRONT ------------------- 

$(".note").live("click", function (e) { 
    console.log("Note click"); 
    $(this).css({"z-index" : zindex}); //Increment zindex 
     zindex++; 

    indexPos = $(this).css("zIndex"); // Get current z-index value 
    e.stopPropagation(); 
}); 

// ----------------- CLONE NOTE ELEMENT ------------------- 


$(document).on("click", "#canvas, .clone", function(e){ 

    var left; 
    var top; 

    if ($(this).hasClass("clone")) { 
     // If the button fired the click put the note at the top of the viewport 
     console.log("Button click"); 
     left = 0 + noteOffset; 
     top = 50 + noteOffset; 
     noteOffset = noteOffset + 15; 
    } else { 
     // If the canvas fired the click put the note on the current mouse position 
     console.log("Canvas click"); 
     left = e.pageX + "px"; 
     top = e.pageY + "px"; 
    } 

    $("#note").clone().insertBefore("#insertAfter").attr("id", "note" + noteID).show() 
     .children(".title").text("Note " + noteID).end().css({ 
      left: left, 
      top: top, 
      "z-index": zindex 
     }); 

    noteID++; 
    zindex++; 

}); 


// ----------------- REMOVE NOTE ELEMENT ------------------- 

$(".close").live("click", function (e) { 
    console.log("Close click"); 
    $(this).parent().remove(); 
    e.stopPropagation(); 
}); 
Cuestiones relacionadas