2013-07-17 3 views
13

Я хочу сделать дополнительный обработчик щелчка (клиент страницу, не могу изменить его JS/HTML), и он должен работать, как это в моем сценарии:stopPropagation и startPropagation

1) event.stopPropagation (пауза клиента нажмите распространения)
2) моя функция (делать свою функцию, когда все сделано делать дальше)
3) event.startPropagation (продолжить стандартное действие клиента)

Прямо сейчас, первая и вторая работа. Третья проблема.
Я знаю event.startPropagation не существует, но я хочу что-то вроде этого. Любые подсказки?

ответ

4

Не прекращайте распространение в первую очередь.

Проверка, если my function выполняет то, что вы хотите, а затем решите, собираетесь ли вы прекратить распространение или нет.

+1

Когда я нажимаю на якорь, моя функция (GET к БД) не успевает выполнить. Я думаю, что его необходимо остановитьPropagation на старте. –

+0

. Вы должны учитывать возможный вред пользователю: пользователь нажимает на что-то, и ничего не происходит до тех пор, пока вызов базы данных не завершится. Хуже того, это может быть долгое время невосприимчивым. – ehdv

+0

Это плохой ответ, потому что остановка распространения часто необходима, когда у вас есть несколько событий, пузырящихся на одном элементе. Именно по этой причине метод существует. – kjdion84

0

Добавьте и удалите обработчик кликов, если вы хотите включить/отключить событие клика соответственно. Потому что event.stopPropagation() остановит события от распространения до дерева.

Update:

Если вы используете JQuery, используйте .trigger() функцию.

http://api.jquery.com/trigger/

9

Вы можете повторно вызвать такой же объект события на родительском узле, f.ex (Jquery). Вам нужно будет скопировать объект события первым и передать его в триггер, чтобы захватить то же свойство событий в пузырьке (f.ex e.pageX):

var copy = $.extend(true, {}, e); 
setTimeout(function() { 
    $(copy.target.parentNode).trigger(copy); 
},500); 
e.stopPropagation(); 

Дем: http://jsfiddle.net/GKkth/

EDIT

Основываясь на ваш комментарий, я думаю, что вы ищете что-то вроде:

$.fn.bindFirst = function(type, handler) { 
    return this.each(function() { 
     var elm = this; 
     var evs = $._data(this).events; 
     if (type in evs) { 
      var handlers = evs[type].map(function(ev) { 
       return ev.handler; 
      }); 
      $(elm).unbind(type).on(type, function(e) { 
       handler.call(elm, e, function() { 
        handlers.forEach(function(fn) { 
         fn.call(elm); 
        }); 
       }); 
      }); 
     } 
    }); 
}; 

Этот прототип позволяет привязать «премиальный обработчик», который содержит функцию next, которая будет выполнять все предыдущие обработчики в том же элементе, когда захотите. Используйте его как:

$('button').click(function() { 
    console.log('first'); 
}).click(function() { 
    console.log('second'); 
}).bindFirst('click', function(e, next) { 
    console.log('do something first'); 
    setTimeout(next, 1000); // holds the other handlers for 1sec 
}); 

DEMO: http://jsfiddle.net/BGuU3/1/

+0

Хорошо, я пробовал это разными способами без хорошего результата. Может быть, я что-то не так. Например: // клиентская сторона, собственный обработчик кликов $ ('p').щелкните (функция (e) { document.location = 'http://www.onet.pl'; }); . // мой сценарий $ ('р') нажмите (функция (е) { e.stopPropagation(); e.preventDefault(); $ .get ( ...., ... ., Функция() { // если все в порядке, то сделайте что-то вроде startPropagation } ) }); –

+2

@ PiotrWójcik звучит так, будто вы ищете 'stopImmediatePropagation()', поскольку обработчик прикреплен к тому же элементу: http://api.jquery.com/event.stopImmediatePropagation/. Просто помните, что это не остановит обработчиков, ранее связанных с выполнением. Или, может быть, вам просто нужно найти обработчиков, которые уже связаны, сохранить их и выполнить позже в своем собственном триггере. – David

+2

@ PiotrWójcik Я отредактировал свой ответ с возможным решением, это то, что вам нужно? – David

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