2012-03-23 2 views
6

Никогда не сталкивайтесь с этим, прежде чем кто-нибудь может дать мне какие-нибудь указания?jQuery stopPropagation()?

Я создаю веб-приложение для создания заметок, как заметки на доске. В настоящий момент кнопка spawn будет создавать ноты, но я хочу сделать так, чтобы пользователь мог щелкнуть в любом месте холста (доски), и в этом месте появится новая заметка.

Вот код для этого: -

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

}); 

Проблема возникает, когда пользователь нажимает на одну из нот, потому что примечания клонируют в холст каждый раз, когда пользователь нажимает на внимание его создания еще одно примечание. Я хочу остановить это поведение и ТОЛЬКО создавать заметку, когда пользователь нажимает на область пустой холста. Я попробовал preventDefauly, stopPropagation и stopImmediate ... но ни один из них, похоже, не имеет никакого влияния.

Я также пробовал их по другим действиям, таким как щелчок на заметке, но просто не может показаться правильным в правильном месте? или я об этом совершенно неправильно?

пример здесь:

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

UPDATE:

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

Это решило проблему отмечает бурлит, однако теперь он предотвращает любые действия, нажмите на классе ноты, я в неизведанные воды здесь! были бы благодарны за любые указатели на то, как вернуть действие щелчка назад для названия и текста заметки :)

ответ

12

Если вы хотите сделать что-то по щелчку на #canvas, но только если щелчок непосредственно на #canvas, а не на своих детей, то два основных варианта доступны для вас:

  1. В соответствии с вашим обновлением вы можете обрабатывать щелчок на каждом дочернем элементе и останавливать его распространение до #canvas, но, конечно, это усложняет другую обработку, которую вы, возможно, захотите сделать для детей.

  2. Тестирование event.target property, чтобы узнать, является ли элемент DOM, инициировавший это событие, вашим #canvas.

Так, отмечая также, что (не связанный с проблемой под рукой), вы можете и должны цепи методы JQuery, а не повторного выбора того же элемента:

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

}); 

Вот демо (с значительно урезанная версия вашего JS, в основном только функция от этого ответа и ваши стили): http://jsfiddle.net/H6XrW/

(Обратите внимание, что вы никогда не должны называть как из .stopImmediatePropagation() и .stopPropagation(), так как первый неявно вызывает их для вас.)

+0

Бриллиант спасибо! отличное объяснение, сжатый код и скрипт JS заставили вас выиграть :) – KryptoniteDove

+0

Splendid! если (e.target! = this) return; работает! – saike

1

Вам нужно будет остановить распространение при нажатии примечаний, так что элемент #canvas не будет уведомлен, когда один из его детей (я предполагаю, что #insertAfter - ребенок #canvas). Прикрепите обработчик щелчка к каждой новой ноте, что предотвращает событие от бурлит:

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

попытались выше, и с живыми, но не радость, ноты еще кипящий, больше идей? – KryptoniteDove

3

Этого код будет остановить щелчки по примечаниям создавать новые ноты:

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

Он работает путем остановки любых переходов на заметках от распространения до холста div.

+0

Это работает, чтобы остановить распространение, которое БОЛЬШОЕ спасибо! :) однако .. любое другое действие клика на заметке также не работает. Почувствуйте, как он собирается вместе, но все же что-то не хватает! – KryptoniteDove

+0

Если вы предполагаете, что существует класс 'note', чем вы, вероятно, так говорите. В противном случае этот подход является более элегантной версией моего упрощенного примера. +1! – jwueller

+0

@elusive Я проверил пример, содержащий класс примечания. –

0

Я немного jquery noob, поэтому может быть более аккуратный способ сделать это, но я проверил следующее, и это работает для меня. Мне было бы интересно услышать от других, если бы я мог сделать что-нибудь лучше. Я не касался HTML или 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(); 
}); 
0

Если вы положили вызов stopEventPropagation внутри холста, вы предотвращаете распространение события click только для участников CANVAS PARENTS. Щелчок «перемещается» из внутреннего элемента вверх в DOM.

Вот ссылка с примером:

http://redfishmemories.blogspot.it/2014/08/jquery-prevent-event-propagation-and.html

Смежные вопросы