2012-03-23 17 views
6

Non ho mai visto prima questo qualcuno può darmi qualche suggerimento?jQuery stopPropagation()?

Sto creando un'app Web per creare note come postarle su una lavagna. Al momento il pulsante spawn genera le note, ma voglio farlo in modo che l'utente possa fare clic in qualsiasi punto della tela (lavagna) e genererà una nuova nota in quella posizione.

ecco il codice per questo: -

$("#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(); 

}); 

Il problema sorge quando l'utente clicca su una delle note, perché le note vengono clonati nella tela ogni volta che l'utente fa clic sulla nota la sua creazione un'altra nota. Voglio interrompere questo comportamento e creare SOLO una nota quando un utente fa clic su un'area vuota. Ho provato a prevenire Defauly, stopPropagation e stopImmediate ... ma nessuno di loro sembra avere alcuna influenza.

Ho anche provato su altre azioni come il clic della nota ma non riesco a trovare quello giusto nel posto giusto? o sto andando su questo completamente nel modo sbagliato?

esempio qui:

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

UPDATE:

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

Questo ha risolto il problema delle note zampillante tuttavia ora impedisce qualunque azione click sulla classe nota, io sono in acque inesplorate qui! apprezzerebbe qualsiasi suggerimento su come riportare le azioni dei clic per il titolo e il testo della nota :)

risposta

12

Se si vuole fare qualcosa al clic su #canvas, ma solo se il clic direttamente sul #canvas e non sui suoi figli, quindi le due opzioni principali disponibili sono:

  1. Come per il tuo aggiornamento puoi gestire il clic su ogni bambino e interromperlo propagandarlo fino a #canvas, ma ovviamente questo complica altre elaborazioni che potresti voler fare per i bambini.

  2. Verificare il event.target property per verificare se l'elemento DOM che ha avviato l'evento è l'elemento #canvas.

Così, notando anche che (non correlato al problema a portata di mano) si può e deve catena metodi di jQuery, piuttosto che ri-selezionando lo stesso 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(); 

}); 

Ecco una demo (con una versione molto cut-down dei tuoi JS, fondamentalmente solo la funzione da questa risposta e gli stili): http://jsfiddle.net/H6XrW/

(si noti che non è mai bisogno di chiamare sia di .stopImmediatePropagation() e .stopPropagation() poiché il primo chiama implicitamente quest'ultimo per voi.)

+0

Brillante grazie !! ottima spiegazione, codice condensato e JS fiddle ti hanno conquistato la vittoria :) – KryptoniteDove

+0

Splendid! se (e.target! = this) return; lavori! – saike

1

È necessario interrompere la propagazione quando si fa clic sulle note, in modo che l'elemento #canvas non venga avvisato quando uno dei suoi figli viene fatto clic (suppongo che #insertAfter sia figlio di #canvas). Fissare un gestore di clic per ogni nuova nota, che impedisce l'evento da zampillante:

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

hanno provato quanto sopra e con vivo, ma nessuna gioia, le note sono ancora bollendo, più idee? – KryptoniteDove

3

Questo codice si fermerà clic sulle note di creare nuove note:

$("#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(); 
}); 

Agisce bloccando qualsiasi clic sulle note dalla propagazione fino al div canvas.

+0

Questo funziona per fermare la propagazione che è GRAZIE grazie! :) tuttavia ... ogni altra azione click sulla nota ora non funziona. Senti come se si stesse avvicinando ma mancava ancora qualcosa! – KryptoniteDove

+0

Se si presume che la classe 'note' esista, si dovrebbe probabilmente dirlo. Altrimenti, questo approccio è una versione più elegante del mio esempio semplificato. +1! – jwueller

+0

@elusive Ho controllato l'esempio che contiene la classe della nota. –

0

Sono un po 'jQuery Noob quindi potrebbe esserci un modo più ordinato per farlo, ma ho provato quanto segue e funziona per me. Sarei interessato a sentire dagli altri se potessi fare qualcosa di meglio. Non ho toccato l'HTML o il 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(); 
});