Обробка події прапорець jQuery


136

У мене є таке:

<form id="myform">
   <input type="checkbox" name="check1" value="check1">
   <input type="checkbox" name="check2" value="check2">
</form>

Як я можу використовувати jQuery для зйомки будь-якої події перевірки, яка виникає в ньому, myformі повідомляти, який прапорець було перемкнено (і знати, чи було він увімкнено чи вимкнено)?

Відповіді:


244
$('#myform :checkbox').change(function() {
    // this will contain a reference to the checkbox   
    if (this.checked) {
        // the checkbox is now checked 
    } else {
        // the checkbox is now no longer checked
    }
});

30
thisвже встановлено для елемента DOM прапорця, тому this.checkedдостатньо. Вам не потрібно буде створювати для нього інший об’єкт jQuery, якщо ви не плануєте маніпулювати ним.
Вальф

18
Просто невеликий наконечник. Ви отримаєте підвищення продуктивності, використовуючи введення:: прапорець у своєму селекторі замість просто: прапорець, оскільки останній перекладається на універсальний селектор *: прапорець.
jimmystormig

23
Клацання не є близьким до жодної події перевірки.
Пітер

27
Це аж ніяк не найкраща відповідь. Якщо у вас є відповідна мітка для введення даних (як <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/>) і ви натискаєте мітку, прапорець буде встановлений, але ця функція НЕ буде викликана. Скористайтеся .change()подією
Патрік

7
Ця відповідь не дає повною мірою відповідь - будь ласка, дивіться відповідь Анурага нижче, що є НАБАГО повнішою (і точнішою) відповіддю. Ця відповідь частково правильна, але, як було зазначено, це не найкраща відповідь.
Карнікс

131

Скористайтеся подією зміни.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});

5
Якщо прапорець прихований, користувач не зможе взаємодіяти з ним. Дайте мені знати, якщо ви мали на увазі щось інше.
Анураг

1
Це не спрацьовує $("input[name=check1]").prop('checked', true). Дивіться jsfiddle.net/Z3E8V/2
Пітер

15
Це за дизайном. Програмна зміна властивості елемента DOM не запускає пов'язаних обробників подій. Вам доведеться стріляти вручну.
Анураг

6
Це має бути обрана відповідь, вона охоплює натискання позначки прапорець
Патрік

3
З документації jQuery: "Оскільки :checkboxрозширення jQuery і не є частиною специфікації CSS, запити, що використовують, :checkboxне можуть скористатися підвищенням продуктивності, що надається нативним querySelectorAll()методом DOM . Для кращої роботи в сучасних браузерах використовуйте [type="checkbox"]замість цього."
NXT

54

Є кілька корисних відповідей, але жодна не охоплює всіх останніх варіантів. З цією метою всі мої приклади також забезпечують наявність відповідних labelелементів, а також дозволяють динамічно додавати прапорці та бачити результати на бічній панелі (шляхом перенаправлення console.log).

  • Прослуховування clickподій увімкнено checkboxes- це не дуже гарна ідея, оскільки це не дозволить змінити клавіатуру чи зміни, внесені в результаті labelнатискання відповідного елемента. Завжди слухайте changeподію.

  • Використовуйте псевдоселектор jQuery :checkbox, а не input[type=checkbox]. :checkboxкоротше і читабельніше.

  • Використовуйте is()за допомогою псевдоселектора jQuery, :checkedщоб перевірити, чи встановлено прапорець. Це гарантовано працює у всіх браузерах.

Основний обробник подій, що додається до існуючих елементів:

$('#myform :checkbox').change(function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/2/

Примітки:

  • Використовує :checkboxселектор, який є кращим для використанняinput[type=checkbox]
  • Це підключається лише до відповідних елементів, які існують на момент реєстрації події.

Делегований обробник подій, приєднаний до елемента предка:

Делеговані обробники подій призначені для ситуацій, коли елементи ще не існують (динамічно завантажуються або створюються) і є дуже корисними. Вони делегують відповідальність елементу предка (звідси термін).

$('#myform').on('change', ':checkbox', function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/4/

Примітки:

  • Це працює, прослуховуючи події (в даному випадку change), щоб піднятися до елемента, що не змінюється (в даному випадку #myform).
  • Потім він застосовує селектор jQuery ( ':checkbox'в даному випадку) лише до елементів ланцюга бульбашок .
  • Потім він застосовує функцію обробника подій лише до тих елементів, які відповідають, що спричинили подію.
  • Використовуйте documentяк за замовчуванням для підключення делегованого обробника подій, якщо нічого іншого не ближче / зручніше.
  • Не використовуйте bodyдля приєднання делегованих подій, оскільки у ньому є помилка (пов’язана зі стилізацією), яка може зупинити її отримання подій миші.

Підсумок делегованих обробників полягає в тому, що відповідні елементи повинні існувати лише в час події, а не тоді, коли обробник події був зареєстрований. Це дозволяє динамічно додавати вміст для генерації подій.

Q: Це повільніше?

Відповідь: Поки події відбуваються зі швидкістю взаємодії з користувачем, вам не потрібно турбуватися про незначну різницю швидкості між делегованим обробником подій та безпосередньо підключеним обробником. Переваги делегації значно перевищують будь-який незначний недолік. Делеговані обробники подій насправді швидше реєструються, оскільки вони зазвичай підключаються до одного відповідного елемента.


Чому не prop('checked', true)припиняється changeподія?

Це насправді задумом. Якщо це призвело до події, ви легко потрапите в ситуацію нескінченних оновлень. Натомість після зміни позначеної властивості надішліть подію зміни до того ж елемента, використовуючи trigger(не triggerHandler):

наприклад, без triggerжодної події не відбувається

$cb.prop('checked', !$cb.prop('checked'));

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/5/

наприклад, з triggerнормальною подією зміни відбувається

$cb.prop('checked', !$cb.prop('checked')).trigger('change');

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/6/

Примітки:

  • Не використовуйте так, triggerHandlerяк запропонував один користувач, оскільки це не буде міхувати події делегованому оброблювачу подій.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/8/

хоча він буде працювати для обробника подій, безпосередньо підключеного до елемента:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/9/

Події, запущені за допомогою .triggerHandler (), не змішують ієрархію DOM; якщо вони не обробляються цільовим елементом безпосередньо, вони нічого не роблять.

Довідка: http://api.jquery.com/triggerhandler/

Якщо хтось має додаткові функції, які, на їхню думку, не охоплені цим, будь ласка, запропонуйте доповнення .


31

Використання нового методу "on" у jQuery (1.7): http://api.jquery.com/on/

    $('#myform').on('change', 'input[type=checkbox]', function(e) {
        console.log(this.name+' '+this.value+' '+this.checked);

    });
  • обробник події буде жити далі
  • буде захоплено, якщо прапорець було змінено клавіатурою, а не просто клацанням

1
Це не спрацьовує $("input[name=check1]").prop('checked', true). Дивіться jsfiddle.net/Z3E8V/2
Пітер

7
Просто додайте .triggerHandler('change');після .propдзвінка. Тоді він переключить вікно І викликає подію.
Ганна


5

Визнаючи той факт, що запитувач спеціально запитував jQuery і що обрана відповідь є правильною, слід зазначити, що ця проблема насправді не потребує jQuery за скажіння. Якщо ви хочете вирішити цю проблему без неї, можна просто встановити onClickатрибут прапорців, яким він або вона хоче додати додаткову функціональність, наприклад:

HTML:

<form id="myform">
  <input type="checkbox" name="check1" value="check1" onClick="cbChanged(this);">
  <input type="checkbox" name="check2" value="check2" onClick="cbChanged(this);">
</form>

javascript:

function cbChanged(checkboxElem) {
  if (checkboxElem.checked) {
    // Do something special
  } else {
    // Do something else
  }
}

Fiddle: http://jsfiddle.net/Y9f66/1/


5
Звичайно, розміщення обробників подій безпосередньо в HTML працює. Але це знаходиться в прямому конфлікті з методами DRY та методами прогресивного вдосконалення. Більш точна відповідь буде "Вам не потрібно jQuery для додавання обробників подій", а замість цього, використовуючи стандартний JS, щоб приєднати обробники кліків у окремий файл JS, а не ставити атрибути onclick у HTML. Здійснюючи це "працює", але хороша практика кодування диктує, що вам слід уникати цього, коли це можливо (що майже завжди є на даний момент, якщо ви не повинні підтримувати IE6 або щось подібне, що навіть MS говорить, що ви більше не повинні цього робити)
Carnix

3

Я спробував код з першої відповіді, він не працює, але я граю, і це працює для мене

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.