Как отменить подпись после события только один раз - PullRequest
0 голосов
/ 18 марта 2011

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

Каждый список выбора имеет 'изменить привязку события следующим образом:

$('#batting-delivery-table tbody').delegate('select[id^="shot-"]', 'change', function () {
    $(this).find('option:first').remove();
});

Как только эта первая опция в списке будет удалена, я хочу убедиться, что никакие другие опции не будут удалены.Я пробовал следующее, но безуспешно:

$('#batting-delivery-table tbody').delegate('select[id^="shot-"]', 'change', function () {
    $(this).find('option:first').remove().undelegate($(this), 'change');
});

Я также пробовал варианты "live" / "die" и подумал бы об использовании $ .one (), если бы я мог визуализировать, какупорядочить мой код.

Предложения приветствуются.

Ответы [ 2 ]

8 голосов
/ 30 апреля 2012

Для этой конкретной цели предназначена функция jQuery .one () .* Описание: Прикрепить обработчик к событию для элементов.Обработчик выполняется не более одного раза для каждого элемента.

1 голос
/ 18 марта 2011

Вы пробовали это?

$("#batting-delivery-table tbody").delegate('select[id^="shot-"]', "change", function () {
    $(this).undelegate("change").find("option:first").remove();

});

Эти селекторы, вероятно, не генерируются динамически на клиенте в течение (более длительного) срока жизни страницы, но скорее загружаются в контент, поэтому нет необходимости использовать функциональность delegate/undelegate. Вероятно, вы просто пытаетесь удалить из них параметр Выбрать элемент из списка , когда пользователь выбирает что-то, и вы не хотите, чтобы снова выбирались фиктивные параметры (что довольно умно и приятно). Я бы просто пошел с bind/unbind:

$("select[id^='shot-']").bind("change", function(evt){
    $(this).unbind("change").find("option:first").remove();
});

Вы можете проверить этот JSFiddle , который работает как положено (и даже имеет несколько улучшений стиля, которые могут вам понравиться).

Наличие динамического выбора

Решение 1

live/delegate функциональность не будет работать так, как вы этого хотите, потому что при попытке отменить делегирование события для определенного элемента делегированное событие все равно соответствует его селектору. Так что это не сработает, потому что событие не связано ни с одним элементом. Детали того, почему это работает таким образом, можно прочитать в документации jQuery, и это выходит за рамки этого ответа.

Лучший способ сделать это - дать фиктивную option специальную class, чтобы вы могли отличать ее от других и удалять, когда она есть, и ничего не делать, когда ее нет. Но событие change будет выполняться независимо.

$("select[id^='shot-']").live("change", function(evt){
    $("option.dummy-option", this).remove();
});

JSFiddle , использующий live регистрацию обработчика.

Решение 2

Вы по-прежнему можете использовать one регистрацию обработчика, но ваша функциональность, которая рекламирует новые элементы выбора в форме, должна будет регистрировать событие вместе с новым элементом select, который добавляется (следовательно, нет глобальной регистрации события). Пример этой функциональности:

$("a.action-add-new").click(function(evt) {
    evt.prevetnDefault();
    $("<select><option>...</option></select>").appendTo("someContainer").one("change", function(){
        $("option:first", this).remove();
    });
});

Решение 3

О, я придумала решение 3, которое использует live (или может использовать delegate) регистрацию событий. Вам следует установить обработчик события на определенный селектор, который вы меняете после запуска изменения.

Когда вы создаете свой выбор, присвойте ему конкретный class, такой как невыбранный . Затем зарегистрируйте событие изменения для этого селектора. В случае изменения просто удалите класс, и он больше не будет запускаться для этого элемента select.

<select id="shot-first" class="unselected">
...
</select>

$("select[id^='shot-'].unselected").live("change", function(evt) {
    $(this).removeClass("unselected").find("option:first").remove();
});

Проверьте рабочее доказательство концепции в this JSFiddle . Работает. Я не знаю, почему я не придумал это раньше. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...