2016-06-05 6 views
2

У меня есть список кнопок для внесения изменений в форум (каждая кнопка содержит уникальное значение атрибута data-mod). Я написал сценарий jquery для обработки последней нажатой кнопки и отправлю ее значение обработчику базы данных php через ajax, который также отправляет настраиваемое оповещение о том, действительно ли модератор хочет выполнить действие или нет (если нет, предупреждение закрывается и ничего не происходит , иначе вызывается функция обратного вызова).jQuery click event weird behavior

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

$(function() { 
var btn; 
// Custom callback function 
function callback(clicked) { 
    $("#result").append("<br/>").append(clicked); 
} 
// Custom alert function 
var alert = { 
    Check: function(fnc, clicked) { 
     $("#alert").show(); 
     $("[data-alert=1]").click(function() { 
     fnc(clicked); 
     alert.Close(); 
     }); 
     $("[data-alert=0]").click(function() { 
     alert.Close(); 
     }); 
    }, 
    Close: function() { 
     $("#alert").hide(); 
     return false; 
    } 
}; 
// Custom button function 
$("[data-mod]").click(function() { 
    btn = $(this); 
    return alert.Check(callback, btn.data("mod")); 
}) 
}); 

Если описание ошибки не было достаточно ясно, что я написал упрощенную скрипку, так что вы можете вносить изменения в код: here.

Кроме того, если ошибка кажется немного запутанным, вот картина воспроизводства: I want only the last clicked button with the "Yes" confirmation button pressed

Заранее спасибо!

ответ

1

Причина в том, что кнопка «Да» и «Нет», отображаемая в предупреждении для разных кнопок, одинакова каждый раз.

Таким образом, каждый раз, когда вы всплываете, вы связываете новую функцию нажатия с кнопкой «да», и когда вы, наконец, щелкните по ней, все связанные функции вызовут.

//This code is called everytime a button is clicked, so your Yes and No 
    //Button will execute as many callbacks when clicked. 
    $("[data-alert=1]").click(function() { 
    fnc(clicked); 
    alert.Close(); 
    }); 
    $("[data-alert=0]").click(function() { 
    alert.Close(); 
    }); 

Что касается решения, просто связать события нажатия Да или Нет один раз (а не каждый раз, когда кнопка нажата), сохраните последняя кнопка нажата в глобальной переменной (или любой другой собственности или любой другой элемент) и извлеките его в своей функции обратного вызова.

$(function() { 
var btn; 
// Custom callback function 
function callback(clicked) { 
    $("#result").append("<br/>").append(clicked); 
} 
// Custom alert function 
var alert = { 
    Check: function(fnc, clicked) { 
     $("#alert").show(); 
     $("#alert").attr("last-clicked", clicked); 
    }, 
    Close: function() { 
     $("#alert").hide(); 
     return false; 
    } 
}; 

//Only called once 
$("[data-alert=1]").click(function() { 
    callback($("#alert").attr("last-clicked")); 
    alert.Close(); 
}); 
$("[data-alert=0]").click(function() { 
    alert.Close(); 
}); 

// Custom button function 
$("[data-mod]").click(function() { 
    btn = $(this); 
    return alert.Check(callback, btn.data("mod")); 
}) 
}); 

Альтернативой является использование .off для remove all previous click bindings к кнопке, как, например:

$("[data-alert=1]").off("click").click(function() { 
    fnc(clicked); 
    alert.Close(); 
    }); 

Но недостатком является то, что он удалит все обратные вызовы для событий щелчка, даже те, что другая часть код мог бы поставить там. Вот почему, может быть, ты лучше делать что-то вроде:

$(document).on("click", "[data-alert=1]", function(...) {...}); 

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

+0

Я смущен. В сценарии реального мира предупреждения загружаются на страницу динамически, с функцией загрузки (шаблон поступает из внешнего файла). С другой стороны, я обновил скрипку, так что она использует .one для кнопки предупреждения, которая вызывает https://jsfiddle.net/fq2mmzfq/1/, по-прежнему такую ​​же ошибку, можете ли вы изменить скрипку? –

+0

@MateusMelo ответ и скрипка отредактированы. – coyotte508

+0

Другое дело, поскольку вы удалили функцию изнутри переменной предупреждения, пользовательская функция обратного вызова теперь ограничивается только обратным вызовом(), которая, если я собираюсь повторно использовать оповещение для другой функции обратного вызова, например somethingElse() это не сработало –